Submission #790163

# Submission time Handle Problem Language Result Execution time Memory
790163 2023-07-22T11:28:29 Z GrindMachine Street Lamps (APIO19_street_lamps) C++17
100 / 100
1405 ms 64172 KB
// Om Namah Shivaya

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

template<typename T> using Tree = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
typedef long long int ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define fastio ios_base::sync_with_stdio(false); cin.tie(NULL)
#define pb push_back
#define endl '\n'
#define sz(a) a.size()
#define setbits(x) __builtin_popcountll(x)
#define ff first
#define ss second
#define conts continue
#define ceil2(x, y) ((x + y - 1) / (y))
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define yes cout << "Yes" << endl
#define no cout << "No" << endl

#define rep(i, n) for(int i = 0; i < n; ++i)
#define rep1(i, n) for(int i = 1; i <= n; ++i)
#define rev(i, s, e) for(int i = s; i >= e; --i)
#define trav(i, a) for(auto &i : a)

template<typename T>
void amin(T &a, T b) {
    a = min(a, b);
}

template<typename T>
void amax(T &a, T b) {
    a = max(a, b);
}

#ifdef LOCAL
#include "debug.h"
#else
#define debug(x) 42
#endif

/*

#of moments when everybody in range was 1

1)
naive

2)
count #of times index has been 1
every time when turning off, add active time of ind
add extra active time if ind is active during query time

3)
every query is good on some suff
find the max time someone in the range is set
all queries after this is good
use segtree for range max queries

4)
can maintain a set of all active 1 segs
when toggle, upd set
also, store all segs (including non-active) and their active time in total
when query, find the sum of active times of all segs [lx,rx] s.t lx <= l <= r <= rx
sweepline + bit

5)
extend 4) idea?
answer queries online
find sum of active times of all segs [lx,rx] s.t lx <= l <= r <= rx
compressed bit at each node of seg
preprocess all compressed bits first, then make updates
alternatively, can also use sparse bit (with unordered_map/gp_hash_table)
also, add [l,r] contribution from the active set (guys from the active set are not in segs)

*/

const int MOD = 1e9 + 7;
const int N = 3e5 + 5;
const int inf1 = int(1e9) + 5;
const ll inf2 = ll(1e18) + 5;

struct compressed_fenwick {
    vector<int> vals,tr;
    int siz = 0;
    bool prepared = false;

    int lsb(int x){
        return x & -x;
    }

    void prepare(){
        prepared = true;
        sort(all(vals));
        vals.resize(unique(all(vals))-vals.begin());
        siz = sz(vals);
        tr = vector<int>(siz+1);
    }

    void pupd(int i, int v){
        if(!prepared){
            vals.pb(i);
            return;
        }

        i = lower_bound(all(vals),i) - vals.begin();
        i++;

        for(; i <= siz; i += lsb(i)){
            tr[i] += v;
        }        
    }

    int get(int i){
        int res = 0;
        for(; i; i -= lsb(i)){
            res += tr[i];
        }
        return res;
    }

    int suff_sum(int i){
        // suff_sum = tot-pref_sum
        i = lower_bound(all(vals),i)-vals.begin()-1+1;
        return get(siz) - get(i);        
    }
};

template<typename T>
struct fenwick {
    int siz;
    vector<compressed_fenwick> tree;
    bool prepared = false;

    fenwick(int n) {
        siz = n;
        tree = vector<compressed_fenwick>(n + 1);
    }

    int lsb(int x) {
        return x & -x;
    }

    void prepare(){
        prepared = true;
        rep(i,siz+1){
            tree[i].prepare();
        }
    }

    void pupd(int i, int pos, T v) {
        while (i <= siz) {
            tree[i].pupd(pos,v);
            i += lsb(i);
        }
    }

    T sum(int i, int pos) {
        T res = 0;

        while (i) {
            res += tree[i].suff_sum(pos);
            i -= lsb(i);
        }

        return res;
    }

    T query(int l, int r, int pos) {
        if (l > r) return 0;
        T res = sum(r,pos) - sum(l-1,pos);
        return res;
    }
};

void solve(int test_case)
{
    int n,q; cin >> n >> q;
    vector<int> a(n+5);
    rep1(i,n){
        char ch; cin >> ch;
        a[i] = ch-'0';
    }

    set<array<int,3>> active;
    vector<array<int,3>> segs;
    fenwick<int> fenw(n+5);

    auto init_active = [&](){
        int l = -1;
        rep1(i,n){
            if(!a[i]){
                if(l != -1){
                    active.insert({l,i-1,0});
                }

                l = -1;
            }
            else{
                if(l == -1){
                    l = i;
                }
            }
        }

        if(l != -1){
            active.insert({l,n,0});
        }
    };

    auto get_seg = [&](int i){
        auto it = active.upper_bound({i+1,-1,-1});
        if(it == active.begin()) return active.end();
        else{
            it--;
            auto [l,r,t] = *it;
            if(l <= i and r >= i){
                return it;
            }
            else{
                return active.end();
            }
        }
    };

    auto insert_seg = [&](set<array<int,3>>::iterator it, int id){
        auto [l,r,t] = *it;
        segs.pb({l,r,id-t});
        fenw.pupd(l,r,id-t);
    };

    init_active();

    vector<array<int,3>> queries(q+5);
    auto oa = a;

    rep1(id,q){
        string t; cin >> t;
        if(t == "toggle"){
            int i; cin >> i;
            queries[id] = {1,i,-1};

            a[i] ^= 1;

            if(!a[i]){
                // unset
                auto it = get_seg(i);
                assert(it != active.end());
                auto [l,r,t] = *it;
                insert_seg(it,id);
                active.erase(it);

                if(l <= i-1){
                    active.insert({l,i-1,id});
                }
                if(i+1 <= r){
                    active.insert({i+1,r,id});
                }
            }
            else{
                // set
                auto it1 = get_seg(i-1);
                auto it2 = get_seg(i+1);
                
                int l = -1, r = -1;

                if(it1 != active.end()){
                    auto curr = *it1;
                    l = curr[0];                    
                    insert_seg(it1,id);
                    active.erase(it1);
                }

                if(it2 != active.end()){
                    auto curr = *it2;
                    r = curr[1];
                    insert_seg(it2,id);
                    active.erase(it2);
                }

                if(l != -1 and r != -1){
                    active.insert({l,r,id});
                }
                else if(l != -1){
                    active.insert({l,i,id});
                }
                else if(r != -1){
                    active.insert({i,r,id});
                }
                else{
                    active.insert({i,i,id});
                }
            }
        }
        else{
            int l,r; cin >> l >> r;
            r--;
            queries[id] = {2,l,r};
        }
    }

    a = oa;
    active.clear();
    segs.clear();
    init_active();

    fenw.prepare();

    rep1(id,q){
        if(queries[id][0] == 1){
            int i = queries[id][1];
            a[i] ^= 1;

            if(!a[i]){
                // unset
                auto it = get_seg(i);
                assert(it != active.end());
                auto [l,r,t] = *it;
                insert_seg(it,id);
                active.erase(it);

                if(l <= i-1){
                    active.insert({l,i-1,id});
                }
                if(i+1 <= r){
                    active.insert({i+1,r,id});
                }
            }
            else{
                // set
                auto it1 = get_seg(i-1);
                auto it2 = get_seg(i+1);
                
                int l = -1, r = -1;

                if(it1 != active.end()){
                    auto curr = *it1;
                    l = curr[0];                    
                    insert_seg(it1,id);
                    active.erase(it1);
                }

                if(it2 != active.end()){
                    auto curr = *it2;
                    r = curr[1];
                    insert_seg(it2,id);
                    active.erase(it2);
                }

                if(l != -1 and r != -1){
                    active.insert({l,r,id});
                }
                else if(l != -1){
                    active.insert({l,i,id});
                }
                else if(r != -1){
                    active.insert({i,r,id});
                }
                else{
                    active.insert({i,i,id});
                }
            }
        }
        else{
            int l = queries[id][1], r = queries[id][2];
            
            auto it = get_seg(l);
            int ans = 0;

            {
                auto [lx,rx,t] = *it;
                if(lx <= l and rx >= r){
                    ans += id-t;
                }
            }

            ans += fenw.query(1,l,r);

            /*

            for(auto [lx,rx,wx] : segs){
                if(lx <= l and rx >= r){
                    ans += wx;
                }
            }
    
            */

            cout << ans << endl;
        }
    }
}

int main()
{
    fastio;

    int t = 1;
    // cin >> t;

    rep1(i, t) {
        solve(i);
    }

    return 0;
}
# Verdict Execution time Memory Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 0 ms 212 KB Output is correct
5 Correct 0 ms 212 KB Output is correct
6 Correct 0 ms 212 KB Output is correct
7 Correct 0 ms 212 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 168 ms 9692 KB Output is correct
2 Correct 215 ms 9960 KB Output is correct
3 Correct 318 ms 11852 KB Output is correct
4 Correct 920 ms 52768 KB Output is correct
5 Correct 947 ms 56316 KB Output is correct
6 Correct 961 ms 56012 KB Output is correct
7 Correct 162 ms 32620 KB Output is correct
8 Correct 131 ms 33904 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2 ms 468 KB Output is correct
2 Correct 1 ms 468 KB Output is correct
3 Correct 1 ms 468 KB Output is correct
4 Correct 1 ms 396 KB Output is correct
5 Correct 1315 ms 64172 KB Output is correct
6 Correct 1231 ms 60844 KB Output is correct
7 Correct 916 ms 55760 KB Output is correct
8 Correct 138 ms 33896 KB Output is correct
9 Correct 63 ms 4012 KB Output is correct
10 Correct 70 ms 4232 KB Output is correct
11 Correct 68 ms 4428 KB Output is correct
12 Correct 123 ms 32616 KB Output is correct
13 Correct 128 ms 34012 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 340 KB Output is correct
2 Correct 1 ms 468 KB Output is correct
3 Correct 1 ms 468 KB Output is correct
4 Correct 2 ms 468 KB Output is correct
5 Correct 302 ms 37704 KB Output is correct
6 Correct 691 ms 47636 KB Output is correct
7 Correct 1012 ms 55524 KB Output is correct
8 Correct 1405 ms 63140 KB Output is correct
9 Correct 235 ms 12912 KB Output is correct
10 Correct 216 ms 15228 KB Output is correct
11 Correct 238 ms 12948 KB Output is correct
12 Correct 218 ms 15300 KB Output is correct
13 Correct 234 ms 13032 KB Output is correct
14 Correct 217 ms 15368 KB Output is correct
15 Correct 125 ms 32588 KB Output is correct
16 Correct 162 ms 33888 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 0 ms 212 KB Output is correct
5 Correct 0 ms 212 KB Output is correct
6 Correct 0 ms 212 KB Output is correct
7 Correct 0 ms 212 KB Output is correct
8 Correct 168 ms 9692 KB Output is correct
9 Correct 215 ms 9960 KB Output is correct
10 Correct 318 ms 11852 KB Output is correct
11 Correct 920 ms 52768 KB Output is correct
12 Correct 947 ms 56316 KB Output is correct
13 Correct 961 ms 56012 KB Output is correct
14 Correct 162 ms 32620 KB Output is correct
15 Correct 131 ms 33904 KB Output is correct
16 Correct 2 ms 468 KB Output is correct
17 Correct 1 ms 468 KB Output is correct
18 Correct 1 ms 468 KB Output is correct
19 Correct 1 ms 396 KB Output is correct
20 Correct 1315 ms 64172 KB Output is correct
21 Correct 1231 ms 60844 KB Output is correct
22 Correct 916 ms 55760 KB Output is correct
23 Correct 138 ms 33896 KB Output is correct
24 Correct 63 ms 4012 KB Output is correct
25 Correct 70 ms 4232 KB Output is correct
26 Correct 68 ms 4428 KB Output is correct
27 Correct 123 ms 32616 KB Output is correct
28 Correct 128 ms 34012 KB Output is correct
29 Correct 1 ms 340 KB Output is correct
30 Correct 1 ms 468 KB Output is correct
31 Correct 1 ms 468 KB Output is correct
32 Correct 2 ms 468 KB Output is correct
33 Correct 302 ms 37704 KB Output is correct
34 Correct 691 ms 47636 KB Output is correct
35 Correct 1012 ms 55524 KB Output is correct
36 Correct 1405 ms 63140 KB Output is correct
37 Correct 235 ms 12912 KB Output is correct
38 Correct 216 ms 15228 KB Output is correct
39 Correct 238 ms 12948 KB Output is correct
40 Correct 218 ms 15300 KB Output is correct
41 Correct 234 ms 13032 KB Output is correct
42 Correct 217 ms 15368 KB Output is correct
43 Correct 125 ms 32588 KB Output is correct
44 Correct 162 ms 33888 KB Output is correct
45 Correct 86 ms 5936 KB Output is correct
46 Correct 131 ms 5888 KB Output is correct
47 Correct 390 ms 22076 KB Output is correct
48 Correct 893 ms 52356 KB Output is correct
49 Correct 76 ms 4372 KB Output is correct
50 Correct 71 ms 4360 KB Output is correct
51 Correct 82 ms 4488 KB Output is correct
52 Correct 79 ms 4436 KB Output is correct
53 Correct 77 ms 4420 KB Output is correct
54 Correct 74 ms 4504 KB Output is correct