답안 #466855

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
466855 2021-08-20T20:57:06 Z thomas_li 가로등 (APIO19_street_lamps) C++17
100 / 100
3592 ms 83620 KB
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pi;
template <class T, class IndexType> struct OfflineSemiSparseFenwickTree2D {
  static_assert(is_integral<IndexType>::value, "IndexType must be integeral");
  int N; vector<int> st, cnt; vector<IndexType> inds; vector<T> BIT;
  int getInd(int i, IndexType j) {
    return upper_bound(inds.begin() + st[i], inds.begin() + st[i] + cnt[i], j)
        - inds.begin() - st[i];
  }
  OfflineSemiSparseFenwickTree2D(int N,
                                 vector<pair<int, IndexType>> updateInds)
      : N(N), st(N + 1, 0), cnt(N + 1, 0) {
    sort(updateInds.begin(), updateInds.end(),
         [&] (const pair<int, IndexType> &a, const pair<int, IndexType> &b) {
      return a.second < b.second;
    });
    vector<IndexType> last(N + 1, IndexType());
    for (auto &&u : updateInds) for (int i = u.first + 1; i <= N; i += i & -i)
      if (cnt[i] == 0 || u.second != last[i]) { cnt[i]++; last[i] = u.second; }
    for (int i = 1; i <= N; i++) st[i] = st[i - 1] + cnt[i - 1];
    inds.resize(st[N] + cnt[N]); BIT.resize(st[N] + cnt[N]);
    fill(cnt.begin(), cnt.end(), 0); for (auto &&u : updateInds)
      for (int i = u.first + 1; i <= N; i += i & -i)
        if (cnt[i] == 0 || u.second != inds[st[i] + cnt[i] - 1])
          inds[st[i] + cnt[i]++] = u.second;
  }
  void update(int i, IndexType j, T v) {
    for (i++; i <= N; i += i & -i)
      for (int s = st[i], c = cnt[i], y = getInd(i, j); y <= c; y += y & -y)
        BIT[s + y - 1] += v;
  }
  T query(int d, IndexType r) {
    T ret = T(); for (d++; d > 0; d -= d & -d)
      for (int s = st[d], y = getInd(d, r); y > 0; y -= y & -y)
        ret += BIT[s + y - 1];
    return ret;
  }
  T query(int d, IndexType l, IndexType r) {
    return query(d, r) - query(d, l - 1);
  }
  T query(int u, int d, IndexType l, IndexType r) {
    return query(d, l, r) - query(u - 1, l, r);
  }
};
int main(){
    cin.tie(0)->sync_with_stdio(0);
    int n,q; cin >> n >> q;
    string s,ts; cin >> s;
    ts = s;
    vector<pi> upd_inds;
    auto fake_upd = [&](int x1, int x2, int y1, int y2){
        upd_inds.emplace_back(x2+1,y2+1);   
        upd_inds.emplace_back(x1,y1);
        upd_inds.emplace_back(x2+1,y1);
        upd_inds.emplace_back(x1,y2+1);
    };
    auto fake_add = [&](int l, int r){
        fake_upd(l,r,l,r);
    };
    set<pi> in;
    vector<vector<array<int,3>>> to_add(q+1);
    for(int i = 0; i < n; i++){
        if(s[i] == '0') continue;
        int ptr = i;
        while(ptr < n && s[ptr] == '1') ptr++;
        // all intervals (l,r) where i <= l,r < ptr will be affected
        to_add[q].push_back({0,i,ptr-1});     
        fake_add(i,ptr-1); in.insert({i,ptr-1});
        i = ptr-1; 
    }
    vector<array<int,3>> qu; vector<bool> sub(q);
    for(int i = 0; i < q; i++){
        string t; cin >> t;
        if(t == "toggle"){
            int x; cin >> x; x--;
            qu.push_back({0,x,0});
            if(s[x] == '0'){
                // merge left and right intervals (if exists) 
                auto rit = in.lower_bound({x,-1});
                int l = x, r = x; bool fl = 0;
                if(rit != in.end() && rit->first == x+1){
                    to_add[i].push_back({1,rit->first,rit->second});
                    r = rit->second; fl = 1; //fake_add(rit->first,rit->second);
                }
                if(rit != in.begin()){
                    auto lft = rit; lft--;
                    if(lft->second == x-1){
                        l = lft->first;
                        //fake_add(lft->first,lft->second);
                        to_add[i].push_back({1,lft->first,lft->second});
                        in.erase(lft);                     }
                }
                if(fl){
                    // erase rit
                    in.erase(in.lower_bound({x,-1}));
                }
                in.insert({l,r});
                fake_add(l,r);
                to_add[i].push_back({0,l,r});
            } else{
                auto cur = in.upper_bound({x,x});  
                if(cur == in.end() || cur->first > x || x > cur->second) cur--;
                auto[l,r] = *cur;
                assert(l <= x && x <= r);
                to_add[i].push_back({1,l,r});
                in.erase(cur); //fake_add(l,r);
                if(l < x){
                    in.insert({l,x-1});
                    fake_add(l,x-1);
                    to_add[i].push_back({0,l,x-1});
                } 
                if(x < r){
                    in.insert({x+1,r});
                    fake_add(x+1,r);
                    to_add[i].push_back({0,x+1,r});
                }
            }
            s[x] = (s[x] == '0' ? '1' : '0');
        } else{
            int a,b; cin >> a >> b;
            a--; b-=2;
            qu.push_back({1,a,b}); bool fl = 0;
            auto cur = in.upper_bound({a,a});
            if(cur == in.end() || cur->first > a || a > cur->second){
                if(cur == in.begin()) fl = 1;
                else cur--;
            }
            if(!fl){
                auto[l,r] = *cur;
                if(l <= a && b <= r) sub[i] = 1;
            } else sub[i] = 0;
        }
    }
    OfflineSemiSparseFenwickTree2D<int,int> ft(n+1,upd_inds);
    auto upd = [&](int x1, int x2, int y1, int y2, int v){
        if(x2 + 1 < n && y2 + 1 < n) ft.update(x2+1,y2+1,v);
        ft.update(x1,y1,v);
        if(x2 + 1 < n)ft.update(x2+1,y1,-v);
        if(y2 + 1 < n)ft.update(x1,y2+1,-v);
    };
    for(auto[t,l,r]:to_add[q]) upd(l,r,l,r,q);
    for(int i = 0; i < q; i++){
        auto add = [&](int l, int r){
            upd(l,r,l,r,q-i-1);   
        };
        auto rmv = [&](int l, int r){
            upd(l,r,l,r,-(q-i-1));        
        };
        if(qu[i][0] == 0){
            for(auto[t,l,r]:to_add[i]){
                if(t == 0) add(l,r);
                else rmv(l,r);
            } 
        } else{
            int a = qu[i][1],b = qu[i][2];
            cout << ft.query(a,b)-sub[i]*(q-i-1) << "\n";
        }
    }

}
// x coordinate is left endpoint, y coordinate is right endpoint
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
3 Correct 1 ms 204 KB Output is correct
4 Correct 1 ms 332 KB Output is correct
5 Correct 1 ms 332 KB Output is correct
6 Correct 1 ms 204 KB Output is correct
7 Correct 1 ms 204 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 434 ms 27264 KB Output is correct
2 Correct 572 ms 27408 KB Output is correct
3 Correct 913 ms 28368 KB Output is correct
4 Correct 2287 ms 64420 KB Output is correct
5 Correct 2281 ms 56148 KB Output is correct
6 Correct 2591 ms 68308 KB Output is correct
7 Correct 154 ms 16716 KB Output is correct
8 Correct 166 ms 18156 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 6 ms 436 KB Output is correct
2 Correct 4 ms 460 KB Output is correct
3 Correct 3 ms 460 KB Output is correct
4 Correct 1 ms 332 KB Output is correct
5 Correct 3592 ms 81116 KB Output is correct
6 Correct 3110 ms 73716 KB Output is correct
7 Correct 2133 ms 56260 KB Output is correct
8 Correct 156 ms 18240 KB Output is correct
9 Correct 105 ms 11036 KB Output is correct
10 Correct 121 ms 13988 KB Output is correct
11 Correct 114 ms 13876 KB Output is correct
12 Correct 148 ms 16664 KB Output is correct
13 Correct 155 ms 18136 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 324 KB Output is correct
2 Correct 2 ms 460 KB Output is correct
3 Correct 3 ms 460 KB Output is correct
4 Correct 4 ms 516 KB Output is correct
5 Correct 707 ms 39572 KB Output is correct
6 Correct 1542 ms 55320 KB Output is correct
7 Correct 2401 ms 68148 KB Output is correct
8 Correct 3555 ms 83620 KB Output is correct
9 Correct 690 ms 34448 KB Output is correct
10 Correct 615 ms 41980 KB Output is correct
11 Correct 690 ms 34468 KB Output is correct
12 Correct 612 ms 41904 KB Output is correct
13 Correct 689 ms 34452 KB Output is correct
14 Correct 607 ms 42108 KB Output is correct
15 Correct 147 ms 16700 KB Output is correct
16 Correct 156 ms 18112 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 204 KB Output is correct
2 Correct 1 ms 204 KB Output is correct
3 Correct 1 ms 204 KB Output is correct
4 Correct 1 ms 332 KB Output is correct
5 Correct 1 ms 332 KB Output is correct
6 Correct 1 ms 204 KB Output is correct
7 Correct 1 ms 204 KB Output is correct
8 Correct 434 ms 27264 KB Output is correct
9 Correct 572 ms 27408 KB Output is correct
10 Correct 913 ms 28368 KB Output is correct
11 Correct 2287 ms 64420 KB Output is correct
12 Correct 2281 ms 56148 KB Output is correct
13 Correct 2591 ms 68308 KB Output is correct
14 Correct 154 ms 16716 KB Output is correct
15 Correct 166 ms 18156 KB Output is correct
16 Correct 6 ms 436 KB Output is correct
17 Correct 4 ms 460 KB Output is correct
18 Correct 3 ms 460 KB Output is correct
19 Correct 1 ms 332 KB Output is correct
20 Correct 3592 ms 81116 KB Output is correct
21 Correct 3110 ms 73716 KB Output is correct
22 Correct 2133 ms 56260 KB Output is correct
23 Correct 156 ms 18240 KB Output is correct
24 Correct 105 ms 11036 KB Output is correct
25 Correct 121 ms 13988 KB Output is correct
26 Correct 114 ms 13876 KB Output is correct
27 Correct 148 ms 16664 KB Output is correct
28 Correct 155 ms 18136 KB Output is correct
29 Correct 2 ms 324 KB Output is correct
30 Correct 2 ms 460 KB Output is correct
31 Correct 3 ms 460 KB Output is correct
32 Correct 4 ms 516 KB Output is correct
33 Correct 707 ms 39572 KB Output is correct
34 Correct 1542 ms 55320 KB Output is correct
35 Correct 2401 ms 68148 KB Output is correct
36 Correct 3555 ms 83620 KB Output is correct
37 Correct 690 ms 34448 KB Output is correct
38 Correct 615 ms 41980 KB Output is correct
39 Correct 690 ms 34468 KB Output is correct
40 Correct 612 ms 41904 KB Output is correct
41 Correct 689 ms 34452 KB Output is correct
42 Correct 607 ms 42108 KB Output is correct
43 Correct 147 ms 16700 KB Output is correct
44 Correct 156 ms 18112 KB Output is correct
45 Correct 146 ms 18160 KB Output is correct
46 Correct 262 ms 18776 KB Output is correct
47 Correct 1018 ms 31460 KB Output is correct
48 Correct 2162 ms 64564 KB Output is correct
49 Correct 124 ms 14872 KB Output is correct
50 Correct 122 ms 14820 KB Output is correct
51 Correct 127 ms 14768 KB Output is correct
52 Correct 129 ms 14856 KB Output is correct
53 Correct 129 ms 14800 KB Output is correct
54 Correct 126 ms 14760 KB Output is correct