Submission #1143742

#TimeUsernameProblemLanguageResultExecution timeMemory
1143742cadmiumskyStreet Lamps (APIO19_street_lamps)C++20
100 / 100
2512 ms204292 KiB
#pragma GCC optimize("Ofast") //#pragma GCC target("avx") #include <bits/stdc++.h> #define all(x) (x).begin(),(x).end() using namespace std; using ll = long long; using ld = long double; //#define int ll #define sz(x) ((int)(x).size()) using pii = pair<int,int>; using tii = tuple<int,int,int>; using tiii = tuple<int,int,int,int>; #define assert kbjsadksja string tmp; void assert(bool ok) { if(!ok) { vector<int> v; v.emplace_back(9); while(1) v.resize(2 * sz(v), v.back() + sz(v)); } } void myassert(bool ok) { if(!ok) { exit(-1); } } const int nmax = 3e5 + 5; int last[nmax]; int rez[nmax]; vector<tii> upds[nmax]; vector<tiii> squares; namespace Beats { set<int> lends; int rend[nmax]; int lval[nmax]; void init(int n, string s) { int lst = 1; for(int i = 1; i <= n; i++) { if(s[i] == '0') { if(i == lst); else { lends.emplace(lst); rend[lst] = i - 1; lval[lst] = 1; } lst = i + 1; } } if(lst <= n) { lends.emplace(lst); rend[lst] = n; lval[lst] = 1; } } void reset(int p, int timer) { auto it = lends.upper_bound(p); myassert(it != lends.begin()); it = prev(it); //cerr << p << '\t' << *it << ' ' << rend[*it] << '\n'; myassert(rend[*it] >= p); squares.emplace_back(*it, rend[*it], lval[*it], timer - 1); if(*it == p && rend[*it] == p) lends.erase(it); else if(*it == p && rend[*it] != p) { rend[p + 1] = rend[*it]; lval[p + 1] = timer; lends.erase(*it); lends.emplace(p + 1); } else if(*it != p && rend[*it] == p) { rend[*it]--; lval[*it] = timer; } else if(*it != p && rend[*it] != p) { rend[p + 1] = rend[*it]; rend[*it] = p - 1; lends.emplace(p + 1); lval[p + 1] = lval[*it] = timer; } } void set(int p, int timer) { auto nx = lends.upper_bound(p); int l = p, r = p; if(nx != lends.end()) { if(*nx == p + 1) { squares.emplace_back(*nx, rend[*nx], lval[*nx], timer - 1); r = rend[*nx]; lends.erase(nx); } } auto prv = lends.upper_bound(p); if(prv != lends.begin()) { prv = prev(prv); if(rend[*prv] == p - 1) { squares.emplace_back(*prv, rend[*prv], lval[*prv], timer - 1); l = *prv; lends.erase(prv); } } lends.emplace(l); rend[l] = r; lval[l] = timer; return; } void liquidate(int T) { for(auto x : lends) { squares.emplace_back(x, rend[x], lval[x], T); } } void print() { //for(auto x : lends) //cerr << x << ", " << rend[x] << '\t'; //cerr << '\n'; } } #define lsb(x) (x & -x) mt19937 rng(8283173); template<typename T> struct Treap { struct Node { Node *l, *r; int pri; T data; } *nil = new Node {0, 0, 0, T()}; Treap() { nil -> l = nil -> r = nil; } using ns = Node*; struct pns { ns l, r; }; ns updnode(ns node, ns x, int t) { (t == 0? node -> l : node -> r) = x; node -> data.pull(node -> l -> data, node -> r -> data); return node; } ns merge(ns l, ns r) { return l == nil? r: r == nil? l: l -> pri > r -> pri? updnode(l, merge(l -> r, r), 1): updnode(r, merge(l, r -> l), 0); } template<class CB> pns split(CB&& cb, ns node) { // here <= cst pns tmp; return node == nil? pns{nil, nil}: cb(node -> data)? (tmp = split(cb, node -> r), tmp.l = updnode(node, tmp.l, 1), tmp): (tmp = split(cb, node -> l), tmp.r = updnode(node, tmp.r, 0), tmp); } ns root = nil; }; struct Val { int poz; int sum, mine; void pull(const Val& x, const Val& y) { sum = x.sum + y.sum + mine; } }; struct AIB : Treap<Val> { void upd(int p, int x) { auto [l, r] = split([&](Val& a) { return a.poz <= p; }, root); root = merge(l, merge(new Node{nil, nil, rng(), Val{p, x, x}}, r)); } int query(int p) { auto [l, r] = split([&](Val& a) { return a.poz <= p; }, root); int rnv = l -> data.sum; root = merge(l, r); return rnv; } }; struct AIB2D { int n; AIB tree[nmax]; void init(int n_) { n = n_ + 1; //for(int i = 1; i < n; i++) tree[i].N = n; } int query(int l, int r) { int sum = 0; while(l < n) sum += tree[l].query(r), l += lsb(l); return sum; } void upd(int l, int r, int p) { while(l > 0) tree[l].upd(r, p), l -= lsb(l); } void donefaking() { //for(int i = 1; i < n; i++) tree[i].donefaking(); } }; vector<pii> startsq[nmax], endsq[nmax]; signed main() { cin.tie(0) -> sync_with_stdio(0); int n, q; cin >> n >> q; vector<pii> qs; string s; cin >> s; s = "#" + s; for(int i = 1; i <= n; i++) last[i] = 1; tmp = s; Beats::init(n, s); for(int i = 2; i <= q + 1; i++) { string act; cin >> act; Beats::print(); //cerr << act << '\n'; if(act == "toggle") { int x; cin >> x; if(s[x] == '1') Beats::reset(x, i); else Beats::set(x, i); s[x] ^= '1' ^ '0'; last[x] = i; qs.emplace_back(-1, x); } else { int l, r; cin >> l >> r; --r; qs.emplace_back(l, r); } } Beats::liquidate(q + 1); //cerr << "---\n"; for(auto &[l, r, u, d] : squares) { //cerr << l << ' ' << r << '\t' << u << ' ' << d << '\n'; startsq[u].emplace_back(l, r); endsq[d + 1].emplace_back(l, r); } AIB2D deja; deja.init(max(n, q) + 2); for(int step = 0; step < 1; step++) { s = tmp; int timer = 1; map<int, pii> opensq; auto effectuate = [&](int i) { for(auto [l, r] : endsq[i]) { if(opensq.count(l)) { deja.upd(r, l, i - opensq[l].second); opensq.erase(l); } else assert(false); //??? } for(auto [l, r] : startsq[i]) opensq[l] = make_pair(r, i); return; }; effectuate(1); for(auto [l, r] : qs) { timer++; if(l == -1) { int x = r; s[x] ^= '1' ^ '0'; rez[timer] = -1; } else { int standard = 0; if(s[l] == '0' || s[r] == '0');// cerr << "fail\n"; else { auto it = opensq.upper_bound(l); assert(it != opensq.begin()); it = prev(it); if(r <= it -> second.first) standard += timer - it -> second.second; } rez[timer] = standard + deja.query(r, l); } if(timer != q + 1) effectuate(timer); } deja.donefaking(); } for(int i = 2; i <= q + 1; i++) { if(rez[i] == -1) continue; cout << rez[i] << '\n'; } return 0; } /** Binecuvanteaza Doamne Ukraina. -- */

Compilation message (stderr)

street_lamps.cpp:16: warning: "assert" redefined
   16 | #define assert kbjsadksja
      | 
In file included from /usr/include/c++/11/cassert:44,
                 from /usr/include/x86_64-linux-gnu/c++/11/bits/stdc++.h:33,
                 from street_lamps.cpp:3:
/usr/include/assert.h:92: note: this is the location of the previous definition
   92 | #  define assert(expr)                                                  \
      | 
street_lamps.cpp: In member function 'void AIB::upd(int, int)':
street_lamps.cpp:178:51: warning: narrowing conversion of 'rng.std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>::operator()()' from 'std::mersenne_twister_engine<long unsigned int, 32, 624, 397, 31, 2567483615, 11, 4294967295, 7, 2636928640, 15, 4022730752, 18, 1812433253>::result_type' {aka 'long unsigned int'} to 'int' [-Wnarrowing]
  178 |       root = merge(l, merge(new Node{nil, nil, rng(), Val{p, x, x}}, r));
      |                                                ~~~^~
#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...