Submission #1092216

#TimeUsernameProblemLanguageResultExecution timeMemory
1092216BLOBVISGOD가로등 (APIO19_street_lamps)C++17
100 / 100
1578 ms60032 KiB
#include "bits/stdc++.h"
using namespace std;
#define rep(i,a,b) for(int i=(a); i<(b); ++i)
#define all(x) x.begin(),x.end()
#define sz(x) int(x.size())
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vvi;

const int M = 300005; 

template<typename T>
struct fentree{
    vector<T> BIT;
    fentree(int n) : BIT(n+1) {}
    fentree(vector<T> a) : BIT(sz(a)+1){
        rep(i,0,sz(a)) BIT[i+1] = a[i]; // how better?
        rep(i,0,sz(BIT)) if (i+(i&(-i))<sz(BIT)) BIT[i+(i&(-i))] += BIT[i];
    }
    void add(int i, T v){
        for(i++; i<sz(BIT); i+=i&(-i)) BIT[i] += v;
    }
    // for halfopen interval [l,r)
    void rangeadd(int l, int r, T v){
        add(l,v);
        add(r,-v);
    }
    // halfopen query : [0,r)
    T get(int r){
        T ans = {};
        for(;r>0;r-=r&(-r)) ans += BIT[r];
        return ans;
    }
    T pointget(int i){
        T ans = {};
        for(i++;i>0;i-=i&(-i)) ans += BIT[i];
        return ans;
    }
    // returns first index r such that the sum of [0,r] is at least v, or returns n
    int lower_bound(T v){
        T sm = {};
        int at = 0;
        for(int w = 1<<__lg(sz(BIT)); w; w/=2){
            if (at+w<sz(BIT) and sm + BIT[at+w] < v){ 
                at += w;
                sm += BIT[at];
            }
        }
        return at;
    }
    // returns first index r such that the sum of [0,r] is at greater than v, or returns n
    int upper_bound(T v){
        T sm = {};
        int at = 0;
        for(int w = 1<<__lg(sz(BIT)); w; w/=2){
            if (at+w<sz(BIT) and sm + BIT[at+w] <= v){
                at += w;
                sm += BIT[at];
            }
        }
        return at;
    }
    // returns first index r such that the sum of [0,r] is at most v, or returns n
    int lower_bound_decr(T v){
        T sm = {};
        int at = 0;
        for(int w = 1<<__lg(sz(BIT)); w; w/=2){
            if (at+w<sz(BIT) and sm + BIT[at+w] > v){
                at += w;
                sm += BIT[at];
            }
        }
        return at;
    }
    // returns first index r such that the sum of [0,r] is less than v, or returns n
    int upper_bound_decr(T v){
        T sm = {};
        int at = 0;
        for(int w = 1<<__lg(sz(BIT)); w; w/=2){
            if (at+w<sz(BIT) and sm + BIT[at+w] >= v){
                at += w;
                sm += BIT[at];
            }
        }
        return at;
    }
};


const int oo = 1e9;

int main(){
    cin.tie(NULL),cin.sync_with_stdio(false);
    
    int n,q; cin >> n >> q;
    string s; cin >> s;


    vector<array<int,4>> blocks; // l,r,starttime, endtime+1;
    set<array<int,3>> segs; // l,r,starttime

    vector<array<int,4>> queries; // l,r,time

    for(int i = 0; i < n; ++i){
        if (s[i]=='0') continue;
        int l = i;
        while (i<n and s[i] == '1') i++;
        int r = i;
        segs.insert({l,r,0});
    }

    segs.insert({-oo,-oo,-oo});
    segs.insert({oo,oo,oo});

    // sweep through events;
    rep(i,0,q){
        string t; cin >> t;
        if (t[0]=='q'){
            int l,r; cin >> l >> r;
            l--,r--;
            queries.push_back({l,r,i,sz(queries)});
        }else{
            int x; cin >> x;
            x--;
            if (s[x]=='0'){
                s[x] = '1';
                auto ub = segs.upper_bound({x,x,oo});
                auto lb = ub; lb--;
                array<int,3> ls = *lb;

                int lo = x, hi = x+1;
                // create new block
                if (ls[1] == x){
                    lo = ls[0];
                    blocks.push_back({ls[0],ls[1],ls[2],i+1});
                    segs.erase(lb);
                }

                ub = segs.upper_bound({x,x,oo});
                array<int,3> us = *ub;

                if (us[0] == x+1){
                    hi = us[1];
                    blocks.push_back({us[0],us[1],us[2],i+1});
                    segs.erase(ub);
                }

                segs.insert({lo,hi,i+1});
            }else{
                s[x] = '0';
                auto ub = segs.upper_bound({x,oo,oo});
                ub--;
                // break up this segment
                array<int,3> v = *ub;
                segs.erase(ub);

                blocks.push_back({v[0],v[1],v[2],i+1});

                if (v[0] < x){
                    segs.insert({v[0],x,i+1});
                }if (v[1] > x+1){
                    segs.insert({x+1,v[1],i+1});
                }
            }
        }
    }

    for(auto [l,r,t] : segs){
        if (abs(l) < oo ) blocks.push_back({l,r,t,q});
    }

    vi ans(sz(queries));
    vi eventans;
    
    struct event{
        int t,x,y,id,v;
        bool operator<(event b){
            return t<b.t or (t==b.t and id < b.id);
        }
    };

    // handle linear events and constant events separately
    // r is inverted, so prefix query gives all nodes (l,r) with l>=L, r<=R
    vector<event> Elin, Econ;
    for (auto [l,r,t1,t2] : blocks){
        Elin.push_back({t1,l,M-r,-1,1}); // assume query is closed
        Elin.push_back({t2,l,M-r,-1,-1});
        Econ.push_back({t1,l,M-r,-1,1-t1});
        Econ.push_back({t2,l,M-r,-1,t2-1});
    }

    for (auto [l,r,t,id] : queries){
        Elin.push_back({t,l,M-r,id,0});
        Econ.push_back({t,l,M-r,id,0});
    }

    sort(all(Elin));
    sort(all(Econ));

    fentree<int> fen(M+5);


    auto rec = [&](int ql, int qr, auto&& rec, bool lin, vector<event>& src) -> void {
        if (ql+1 == qr) return;

        int mid = (ql+qr)/2;

        rec(ql,mid,rec,lin, src);
        rec(mid,qr,rec,lin, src);

        // contribute L to R || NOTE CLOSED INTERVALS
        struct ev{
            int x, y, id, v;
            bool operator<(ev b){
                return x<b.x or (x==b.x and id<b.id);
            }
        };

        vector<ev> E;
        rep(i,ql,mid){
            auto& e = src[i];
            if (e.id<0) E.push_back(ev{e.x,e.y,e.id,e.v});
        }
        rep(i,mid,qr){
            auto& e = src[i];
            if (e.id>=0) E.push_back(ev{e.x,e.y,e.id,e.t});
        }

        sort(all(E));

        for(auto& e : E){
            if (e.id<0){
                fen.add(e.y,e.v);
            }else{
                ans[e.id] += fen.get(e.y+1)*(lin?e.v:1);
            }
        }   

        // undo fenwick operations
        for(auto& e : E){
            if (e.id<0){
                fen.add(e.y,-e.v);
            }
        }
    };

    rec(0,sz(Elin),rec,1,Elin);
    rec(0,sz(Econ),rec,0,Econ);

    for(auto c : ans) cout << c << '\n';
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...