답안 #357590

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
357590 2021-01-24T08:20:32 Z Thistle Sterilizing Spray (JOI15_sterilizing) C++14
75 / 100
2275 ms 254592 KB
#pragma GCC target ("avx")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define _USE_MATH_DEFINES
#include<iostream>
#include<string>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<list>
#include<iomanip>
#include<vector>
#include<random>
#include<functional>
#include<algorithm>
#include<stack>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<unordered_map>
#include<climits>
#include<fstream>
#include<complex>
#include<time.h>
#include<cassert>
#include<functional>
#include<numeric>
#include<tuple>
using namespace std;
using ll = long long;
using ld = long double;
using H = pair<ll, ll>;
using P = pair<ll, H>;
using vi = vector<ll>;
#define all(a) (a).begin(),(a).end()
#define fs first
#define sc second
#define xx first
#define yy second.first
#define zz second.second
#define Q(i,j,k) mkp(i,mkp(j,k))
#define rng(i,s,n) for(ll i = (s) ; i < (n) ; i++)
#define rep(i,n) rng(i, 0, (n))
#define mkp make_pair
#define vec vector
#define pb emplace_back
#define siz(a) int(a.size())
#define crdcomp(b) sort(all((b)));(b).erase(unique(all((b))),(b).end())
#define getidx(b,i) (lower_bound(all(b),(i))-(b).begin())
#define ssp(i,n) (i==(ll)(n)-1?"\n":" ")
#define ctoi(c) (int)(c-'0')
#define itoc(c) (char)(c+'0')
#define cyes printf("Yes\n")
#define cno printf("No\n")
#define cdf(n) for(int quetimes_=(n);quetimes_>0;quetimes_--)
#define gcj printf("Case #%lld: ",qq123_+1)
#define readv(a,n) a.resize(n,0);rep(i,(n)) a[i]=read()
#define found(a,x) (a.find(x)!=a.end())
constexpr ll mod = (ll)1e9 + 7;
constexpr ll Mod = 998244353;
constexpr ld EPS = 1e-10;
constexpr ll inf = (ll)3 * 1e18;
constexpr int Inf = (ll)15 * 1e8;
constexpr int dx[] = { -1,1,0,0 }, dy[] = { 0,0,-1,1 };
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }
ll read() { ll u, k = scanf("%lld", &u); return u; }
string reads() { string s; cin >> s; return s; }
H readh(short g = 0) { H u; int k = scanf("%lld %lld", &u.fs, &u.sc); if (g == 1) u.fs--, u.sc--; if (g == 2) u.fs--; return u; }
bool ina(H t, int h, int w) { return 0 <= t.fs && t.fs < h && 0 <= t.sc && t.sc < w; }
bool ina(int t, int l, int r) { return l <= t && t < r; }
ll gcd(ll i, ll j) { return j ? gcd(j, i % j) : i; }
ll ppc(ll x) {
    int sum = 0; for (int i = 0; i < 60; i++)if ((1ll << i) & x) sum++;
    return sum;
}
template<typename T>
void fin(T x) { cout << x << endl; exit(0); }

template<typename T>
class csum {
    vec<T> v;
public:
    csum(vec<T>& a) :v(a) { build(); }
    csum() {}
    csum(int sz) { init(sz); }
    void init(int sz) { v = vector<T>(sz + 1, 0); }
    void init(vec<T>& a) { v = a; build(); }
    void build() {
        for (int i = 1; i < v.size(); i++) v[i] += v[i - 1];
    }
    void add(int l, int r, T x) {
        v[l] += x;
        v[r] -= x;
    }//[l,r)
    void add(int t, T x) {
        v[t] += x;
    }//[l,r)
    //[l,r]
    T a(int l, int r) {
        if (r < l) return 0;
        return v[r] - (l == 0 ? 0 : v[l - 1]);
    }
    //[l,r)
    T b(int l, int r) {
        return a(l, r - 1);
    }
    T a(pair<int, int>t) {
        return a(t.first, t.second);
    }
    T b(pair<int, int>t) {
        return b(t.first, t.second);
    }
    T operator[](int x)const {
        return v[x];
    }
};
template<ll mod>
class modint {
public:ll v;
      modint(ll v = 0) { s(v % mod + mod); }
      constexpr static int fn_ = (ll)2e6 + 5;
      static vector<modint>fact, comp;
      modint pow(ll x) const {
          modint b(v), c(1);
          while (x) {
              if (x & 1) c *= b;
              b *= b;
              x >>= 1;
          }
          return c;
      }
      inline modint& s(int vv) {
          v = vv < mod ? vv : vv - mod;
          return *this;
      }
      inline modint inv()const { return pow(mod - 2); }
      inline modint operator-()const { return modint() - *this; }
      inline modint& operator+=(const modint b) { return s(v + b.v); }
      inline modint& operator-=(const modint b) { return s(v + mod - b.v); }
      inline modint& operator*=(const modint b) { v = v * b.v % mod; return *this; }
      inline modint& operator/=(const modint b) { v = v * b.inv().v % mod; return *this; }
      inline modint operator+(const modint& b) const { return modint(v) += b; }
      inline modint operator-(const modint& b) const { return modint(v) -= b; }
      inline modint operator*(const modint& b) const { return modint(v) *= b; }
      inline modint operator/(const modint& b) const { return modint(v) /= b; }
      friend ostream& operator<<(ostream& os, const modint& m) {
          return os << m.v;
      }
      friend istream& operator>>(istream& is, modint& m) {
          int x; is >> x; m = modint(x);
          return is;
      }
      bool operator<(const modint& r)const { return v < r.v; }
      bool operator>(const modint& r)const { return v > r.v; }
      bool operator<=(const modint& r)const { return v <= r.v; }
      bool operator>=(const modint& r)const { return v >= r.v; }
      bool operator==(const modint& r)const { return v == r.v; }
      bool operator!=(const modint& r)const { return v != r.v; }
      explicit operator bool()const { return v; }
      explicit operator int()const { return v; }
      modint comb(modint k) {
          if (k > *this) return modint();
          if (fact.empty()) combinit();
          if (v >= fn_) {
              if (k > *this - k) k = *this - k;
              modint tmp(1);
              for (int i = v; i >= v - k.v + 1; i--) tmp *= modint(i);
              return tmp * comp[k.v];
          }
          return fact[v] * comp[k.v] * comp[v - k.v];
      }//nCk
      modint perm(modint k) {
          if (k > *this) return modint();
          if (fact.empty()) combinit();
          if (v >= fn_) {
              modint tmp(1);
              for (int i = v; i >= v - k.v + 1; i--) tmp *= modint(i);
              return tmp;
          }
          return fact[v] * comp[v - k.v];
      }//nPk
      static void combinit() {
          fact.assign(fn_, modint());
          fact[0] = 1;
          for (int i = 1; i < fn_; i++) fact[i] = fact[i - 1] * modint(i);
          comp.assign(fn_, modint());
          comp[fn_ - 1] = fact[fn_ - 1].inv();
          for (int i = fn_ - 2; i >= 0; i--) comp[i] = comp[i + 1] * modint(i + 1);
      }
};
using mint = modint<ll(1e9 + 7)>; template<>vec<mint> mint::fact = vec<mint>(); template<>vec<mint> mint::comp = vec<mint>();
//--------------------------------------------------------------
//--------------------------------------------------------------
template<class T>
class LazySegmentTree {
protected:
    using UPF = function<void(T&, const int&)>;
    using QRF = function<void(T&, const T)>;
    using F = function<bool(T a)>;
    using ll = long long;
    int n, rr;
    vector<T>dat;
    vector<int>len;

    LazySegmentTree() {}
    LazySegmentTree(int size) { init(size); }
    LazySegmentTree(vector<T>& v) {
        init(v);
    }
    virtual ~LazySegmentTree() {}

    virtual void eval(const T& par, T& a, const int& al) = 0;
    virtual void fold(T& par, const int& pl) = 0;
    virtual T proc(const T& a, const int& al, const T& b, const int& bl) = 0;

public:
    void init(int size) {
        n = size, rr = 1;
        while (rr < n) rr <<= 1;
        dat.assign(2 * rr - 1, T());
        len.assign(2 * rr - 1, 0);
        for (int i = 0; i < n; i++) {
            len[i + rr - 1] = 1;
            dat[i + rr - 1] = T();
        }
        for (int i = rr - 2; i >= 0; i--) {
            len[i] = len[i * 2 + 1] + len[i * 2 + 2];
            dat[i] = proc(dat[i * 2 + 1], len[i * 2 + 1], dat[i * 2 + 2], len[i * 2 + 2]);
        }
    }
    void init(vector<T>& v) {
        n = (int)v.size(), rr = 1;
        while (rr < n) rr <<= 1;
        dat.assign(2 * rr - 1, T());
        len.assign(2 * rr - 1, 0);
        for (int i = 0; i < n; i++) {
            dat[i + rr - 1] = v[i];
            len[i + rr - 1] = 1;
        }
        for (int i = rr - 2; i >= 0; i--) {
            len[i] = len[i * 2 + 1] + len[i * 2 + 2];
            dat[i] = proc(dat[i * 2 + 1], len[i * 2 + 1], dat[i * 2 + 2], len[i * 2 + 2]);
        }
    }
    //one point update
    void set(int at, T x) {
        upd(at, at + 1, [&x](T& a, const int& len){a = x; });
    }
    void upd(int a, int b, UPF func) {
        upd(0, a, b, 0, rr, func);
    }
    T qry(int a, int b) {
        return qry(0, a, b, 0, rr);
    }
    T get0() {
        return dat[0];
    }
    //func([a,i))==true, func([a,i+1))==false
    int lb(int a, int b, F func) {
        T e = T();
        int lgt = 0;
        return lb(0, a, b, 0, rr, func, e, lgt);
    }
    //func([i,b))==true, func([i-1,b))==false
    int ub(int a, int b, F func) {
        T e = T();
        int lgt = 0;
        return ub(0, a, b, 0, rr, func, e, lgt);
    }
private:
    void upd(int i, const int& a, const int& b, int l, int r, UPF& func) {
        if (b <= l || r <= a) return;
        if (a <= l && r <= b) {
            func(dat[i], len[i]);
            return;
        }
        eval(dat[i], dat[i * 2 + 1], len[i * 2 + 1]);
        eval(dat[i], dat[i * 2 + 2], len[i * 2 + 2]);
        fold(dat[i], len[i]);

        upd(i * 2 + 1, a, b, l, (l + r) / 2, func);
        upd(i * 2 + 2, a, b, (l + r) / 2, r, func);

        dat[i] = proc(dat[i * 2 + 1], len[i * 2 + 1], dat[i * 2 + 2], len[i * 2 + 2]);
    }
    T qry(int i, const int& a, const int& b, int l, int r) {
        if (b <= l || r <= a) return T();
        if (a <= l && r <= b) return dat[i];

        eval(dat[i], dat[i * 2 + 1], len[i * 2 + 1]);
        eval(dat[i], dat[i * 2 + 2], len[i * 2 + 2]);
        fold(dat[i], len[i]);

        return proc(qry(i * 2 + 1, a, b, l, (l + r) / 2), len[i * 2 + 1],
            qry(i * 2 + 2, a, b, (l + r) / 2, r), len[i * 2 + 2]);
    }
    int lb(int i, int a, int b, int l, int r, F& func, T& wa, int& lgt) {
        if (b <= l || r <= a) return b;
        if (a <= l && r <= b) {
            if (func(proc(wa, lgt, dat[i], len[i]))) {
                wa = proc(wa, lgt, dat[i], len[i]);
                lgt += len[i];
                return b;
            }
            if (r - l == 1) return l;
        }
        eval(dat[i], dat[i * 2 + 1], len[i * 2 + 1]);
        eval(dat[i], dat[i * 2 + 2], len[i * 2 + 2]);
        fold(dat[i], len[i]);

        int tmp = lb(i * 2 + 1, a, b, l, (l + r) / 2, func, wa, lgt);
        if (tmp < b) return tmp;
        return lb(i * 2 + 2, a, b, (l + r) / 2, r, func, wa, lgt);
    }
    int ub(int i, int a, int b, int l, int r, F& func, T& wa, int& lgt) {
        if (b <= l || r <= a) return a;
        if (a <= l && r <= b) {
            if (func(proc(dat[i], len[i], wa, lgt))) {
                wa = proc(dat[i], len[i], wa, lgt);
                lgt += len[i];
                return a;
            }
            if (r - l == 1) return r;
        }
        eval(dat[i], dat[i * 2 + 1], len[i * 2 + 1]);
        eval(dat[i], dat[i * 2 + 2], len[i * 2 + 2]);
        fold(dat[i], len[i]);

        int tmp = ub(i * 2 + 2, a, b, (l + r) / 2, r, func, wa, lgt);
        if (tmp > a) return tmp;
        return ub(i * 2 + 1, a, b, l, (l + r) / 2, func, wa, lgt);
    }
};
ll k;
template<class T>
class Segtree :public LazySegmentTree<T> {
    using Base = LazySegmentTree<T>;
public:
    Segtree() {}
    Segtree(int size) {
        init(size);
    }
    Segtree(vector<ll> v) {
        init(v);
    }
    void init(int size) {
        Base::init(size);
    }
    void init(vector<ll> v) {
        vector<T>r(v.size());
        for (int i = 0; i < v.size(); i++) {
            r[i] = T(v[i], 0);
        }
        Base::init(r);
    }

    void update(int a, ll x) {
        Base::set(a, T(x, 0));
    }
    void div(int a, int b) {
        Base::upd(a, b, [](T& dat, const int& len) {
            if (!dat.u.empty()) {
                dat.v = dat.u[0];
                dat.u.pop_front();
            }
            else dat.v = 0;
            dat.l++;
            });
    }
    ll query(int a, int b) {
        return Base::qry(a, b).v;
    }
    T get0() {
        return Base::get0();
    }
private:
    void eval(const T& par, T& a, const int& al)override {
        if (par.l >= siz(a.u)) {
            a.u.clear();
            a.v = 0;
        }
        else {
            rep(i, par.l) {
                a.v = a.u[0];
                a.u.pop_front();
            }
        }
        a.l += par.l;
    }
    void fold(T& par, const int& pl) override {
        par.l = 0;
    }
    T proc(const T& a, const int& al, const T& b, const int& bl)override {
        T ret = T(a.v + b.v, 0);
        rep(i, 33) ret.u[i] = (siz(a.u) <= i ? 0ll : a.u[i]) +
            (siz(b.u) <= i ? 0ll : b.u[i]);
        return ret;
    }
};
struct Mn {
    ll v, l;//現在の総和、処分していない間に何回割ったか
    deque<ll> u;//1回割ったときの総和、2回割ったときの総和、3回…
    Mn() :v(0), l(0), u(deque<ll>(33, 0)) {}
    Mn(ll v, ll l) :v(v), l(l), u(deque<ll>(33, 0)) {
        ll g = v;
        rep(i, 33) {
            g /= k;
            u[i] = g;
        }
    }
};
signed main() {
    int n, q; cin >> n >> q >> k;
    vi a; readv(a, n);
    Segtree<Mn>seg(a);
    rep(i, q) {
        int t; ll l, r; cin >> t >> l >> r;
        l--;
        if (t == 1) seg.update(l, r);
        else if (t == 2) seg.div(l, r);
        else cout << seg.query(l, r) << endl;
    }
}

Compilation message

sterilizing.cpp: In function 'll read()':
sterilizing.cpp:69:19: warning: unused variable 'k' [-Wunused-variable]
   69 | ll read() { ll u, k = scanf("%lld", &u); return u; }
      |                   ^
sterilizing.cpp: In function 'H readh(short int)':
sterilizing.cpp:71:33: warning: unused variable 'k' [-Wunused-variable]
   71 | H readh(short g = 0) { H u; int k = scanf("%lld %lld", &u.fs, &u.sc); if (g == 1) u.fs--, u.sc--; if (g == 2) u.fs--; return u; }
      |                                 ^
sterilizing.cpp: In instantiation of 'void Segtree<T>::init(std::vector<long long int>) [with T = Mn]':
sterilizing.cpp:347:9:   required from 'Segtree<T>::Segtree(std::vector<long long int>) [with T = Mn]'
sterilizing.cpp:418:21:   required from here
sterilizing.cpp:354:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  354 |         for (int i = 0; i < v.size(); i++) {
      |                         ~~^~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 19 ms 620 KB Output is correct
2 Incorrect 16 ms 2412 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 2203 ms 126592 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 578 ms 16368 KB Output is correct
2 Correct 421 ms 123244 KB Output is correct
3 Correct 591 ms 123372 KB Output is correct
4 Correct 1652 ms 63340 KB Output is correct
5 Correct 2201 ms 253676 KB Output is correct
6 Correct 2201 ms 253548 KB Output is correct
7 Incorrect 2209 ms 253608 KB Output isn't correct
8 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1376 ms 128236 KB Output is correct
2 Correct 1590 ms 129132 KB Output is correct
3 Correct 1045 ms 123756 KB Output is correct
4 Correct 1715 ms 69100 KB Output is correct
5 Correct 2224 ms 254524 KB Output is correct
6 Correct 2250 ms 254592 KB Output is correct
7 Correct 2243 ms 254572 KB Output is correct
8 Correct 2275 ms 254444 KB Output is correct
9 Correct 2061 ms 254444 KB Output is correct
10 Correct 2091 ms 254444 KB Output is correct
11 Correct 2044 ms 254268 KB Output is correct
12 Correct 2113 ms 254316 KB Output is correct