#include <bits/stdc++.h>
using namespace std;
using ii = pair<int, int>;
const int inf = 1e9;
#define X first
#define Y second
vector<ii> P;
int n, q;
char s[300007];
vector<ii> Q;
bool compy(ii a, ii b) {
return (ii){a.Y, a.X} < (ii){b.Y, b.X};
}
struct SegmentTree1D {
vector<ii> P;
vector<int> d;
int lv;
int miny, maxy, v;
SegmentTree1D(int L, int R) {
lv = R - L + 1;
d.resize(2 * lv + 3);
P.resize(lv);
for(int i = 0 ; i < lv ; i++)
P[i] = ::P[L + i];
sort(P.begin(), P.end(), compy);
}
void insert(int w, int l, int r, bool b) {
if(P[r].Y < miny || P[l].Y > maxy)
return ;
if(P[l].Y >= miny && P[r].Y <= maxy) {
//~ cout << "ins1d on " << l << " " << r << endl;
d[w] += v;
return ;
}
insert(2 * w, l, (l + r) / 2, 0);
insert(2 * w + 1, (l + r) / 2 + 1, r, 0);
}
int query(int w, int l, int r, ii p) {
int res = d[w];
if(l == r)
return res;
int mid = (l + r) / 2;
if(p.Y < P[mid].Y || (p.Y == P[mid].Y && p.X <= P[mid].X))
res += query(2 * w, l, mid, p);
else
res += query(2 * w + 1, mid + 1, r, p);
return res;
}
void insert(int miny, int maxy, int v) {
this->miny = miny;
this->maxy = maxy;
this->v = v;
insert(1, 0, lv - 1, 0);
}
int query(ii p) {
return query(1, 0, lv - 1, p);
}
};
struct SegmentTree2D {
int lv;
vector<SegmentTree1D*> d;
int maxx, miny, maxy, v;
void build(int w, int l, int r) {
if(w >= 2 * lv)
return ;
d[w] = new SegmentTree1D(l, r);
build(2 * w, l, (l + r) / 2);
build(2 * w + 1, (l + r) / 2 + 1, r);
}
SegmentTree2D() {
lv = 2;
sort(P.begin(), P.end());
P.resize(distance(P.begin(), unique(P.begin(), P.end())));
while(lv < P.size())
lv *= 2;
while(P.size() < lv)
P.push_back({inf, inf});
d.resize(2 * lv + 3);
build(1, 0, lv - 1);
}
void insert(int w, int l, int r) {
if(P[l].X > maxx)
return ;
if(P[r].X <= maxx) {
//~ cout << "ins2d on " << l << " " << r << endl;
d[w]->insert(miny, maxy, v);
return ;
}
insert(2 * w, l, (l + r) / 2);
insert(2 * w + 1, (l + r) / 2 + 1, r);
}
int query(int w, int l, int r, ii p) {
if(w >= 2 * lv)
return 0;
if(P[l] > p)
return 0;
if(p > P[r])
return 0;
int res = d[w]->query(p);
res += query(2 * w, l, (l + r) / 2, p);
res += query(2 * w + 1, (l + r) / 2 + 1, r, p);
return res;
}
void insert(int maxx, int miny, int maxy, int v) {
//~ cout << "ins x<=" << maxx << " y>=" << miny << endl;
this->maxx = maxx;
this->miny = miny;
this->maxy = maxy;
this->v = v;
insert(1, 0, lv - 1);
}
int query(ii p) {
return query(1, 0, lv - 1, p);
}
};
SegmentTree2D *ST;
set<ii> segments;
void init_segments() {
for(int i = 1 ; i <= n ; ) {
int j = i;
while(j <= n && s[j] == '1')
j++;
if(j > i)
segments.insert({i, j - 1});
i = j + 1;
}
}
int query(ii p, int t) {
bool active = false;
auto it = segments.upper_bound({p.X, inf});
if(it != segments.begin()) {
it = prev(it);
auto p2 = *it;
if(p2.Y >= p.Y)
active = true;
}
int v = ST->query(p);
//~ cout << "query " << p.X << " " << p.Y << " " << active << " " << v << " " << t << endl;
if(active)
v += t;
return v;
}
void tree_insert(int a, int b, int c, int d, int v) {
//~ cout << "ins" << a << " " << b << " " << c << " " << d << " " << v << endl;
ST->insert(b, c, d, v);
ST->insert(a - 1, c, d, -v);
}
void light_up(int i, int t) {
auto rightit = segments.upper_bound((ii){i, inf});
auto leftit = segments.end();
if(rightit != segments.begin())
leftit = prev(rightit);
ii left = {-inf, -inf}, right = {inf, inf};
if(rightit != segments.end()) right = *rightit;
if(leftit != segments.end()) left = *leftit;
if(left.Y == i - 1 && right.X == i + 1) {
tree_insert(left.X, i, i, right.Y, -t);
segments.erase(left);
segments.erase(right);
segments.insert({left.X, right.Y});
} else if(left.Y == i - 1) {
tree_insert(left.X, i, i, i, -t);
segments.erase(left);
segments.insert({left.X, i});
} else if(right.X == i + 1) {
tree_insert(i, i, i, right.Y, -t);
segments.erase(right);
segments.insert({i, right.Y});
} else {
tree_insert(i, i, i, i, -t);
segments.insert({i, i});
}
}
void light_down(int i, int t) {
auto it = segments.upper_bound((ii){i, inf});
it = prev(it);
ii seg = *it;
tree_insert(seg.X, i, i, seg.Y, t);
segments.erase(seg);
if(seg.X <= i - 1)
segments.insert({seg.X, i - 1});
if(i + 1 <= seg.Y)
segments.insert({i + 1, seg.Y});
}
void toggle(int i, int t) {
if(s[i] == '1') {
s[i] = '0';
light_down(i, t);
} else {
s[i] = '1';
light_up(i, t);
}
}
int main() {
scanf("%d%d", &n, &q);
scanf(" %s", s + 1);
for(int i = 0 ; i < q ; i++) {
char comm[10];
scanf(" %s", comm);
if(comm[0] == 't') {
int i;
scanf("%d", &i);
Q.emplace_back(i, -1);
} else {
int a, b;
scanf("%d%d", &a, &b);
Q.emplace_back(a, b);
P.push_back({a, b - 1});
}
}
ST = new SegmentTree2D();
//~ for(auto p : P)
//~ cout << p.X << " " << p.Y << "; " ;
//~ cout << endl;
init_segments();
int t = 1;
for(auto q : Q) {
//~ cout << "S: ";
//~ for(auto p : segments)
//~ cout << p.X << " " << p.Y << "; ";
//~ cout << endl;
if(q.Y == -1)
toggle(q.X, t);
else
printf("%d\n", query({q.X, q.Y - 1}, t));
t++;
}
return 0;
}
Compilation message
street_lamps.cpp: In constructor 'SegmentTree2D::SegmentTree2D()':
street_lamps.cpp:94:12: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
while(lv < P.size())
~~~^~~~~~~~~~
street_lamps.cpp:96:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
while(P.size() < lv)
~~~~~~~~~^~~~
street_lamps.cpp: In function 'int main()':
street_lamps.cpp:235:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d%d", &n, &q);
~~~~~^~~~~~~~~~~~~~~~
street_lamps.cpp:236:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf(" %s", s + 1);
~~~~~^~~~~~~~~~~~~~
street_lamps.cpp:240:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf(" %s", comm);
~~~~~^~~~~~~~~~~~~
street_lamps.cpp:243:9: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d", &i);
~~~~~^~~~~~~~~~
street_lamps.cpp:247:9: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d%d", &a, &b);
~~~~~^~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
5 ms |
256 KB |
Output is correct |
2 |
Correct |
5 ms |
376 KB |
Output is correct |
3 |
Correct |
5 ms |
376 KB |
Output is correct |
4 |
Correct |
5 ms |
376 KB |
Output is correct |
5 |
Correct |
5 ms |
376 KB |
Output is correct |
6 |
Correct |
5 ms |
376 KB |
Output is correct |
7 |
Correct |
5 ms |
376 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
245 ms |
6760 KB |
Output is correct |
2 |
Correct |
313 ms |
6876 KB |
Output is correct |
3 |
Correct |
537 ms |
8796 KB |
Output is correct |
4 |
Correct |
1778 ms |
80220 KB |
Output is correct |
5 |
Correct |
2249 ms |
157132 KB |
Output is correct |
6 |
Correct |
1483 ms |
80044 KB |
Output is correct |
7 |
Correct |
2617 ms |
153672 KB |
Output is correct |
8 |
Correct |
2745 ms |
155200 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
5 ms |
376 KB |
Output is correct |
2 |
Correct |
6 ms |
504 KB |
Output is correct |
3 |
Correct |
7 ms |
760 KB |
Output is correct |
4 |
Correct |
8 ms |
760 KB |
Output is correct |
5 |
Correct |
576 ms |
8484 KB |
Output is correct |
6 |
Correct |
1872 ms |
79452 KB |
Output is correct |
7 |
Correct |
2862 ms |
156492 KB |
Output is correct |
8 |
Correct |
3823 ms |
312776 KB |
Output is correct |
9 |
Correct |
453 ms |
8920 KB |
Output is correct |
10 |
Correct |
428 ms |
7360 KB |
Output is correct |
11 |
Correct |
559 ms |
13644 KB |
Output is correct |
12 |
Correct |
3881 ms |
311376 KB |
Output is correct |
13 |
Correct |
3889 ms |
312780 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
7 ms |
760 KB |
Output is correct |
2 |
Correct |
7 ms |
760 KB |
Output is correct |
3 |
Correct |
6 ms |
504 KB |
Output is correct |
4 |
Correct |
6 ms |
376 KB |
Output is correct |
5 |
Correct |
4168 ms |
314992 KB |
Output is correct |
6 |
Correct |
2849 ms |
156768 KB |
Output is correct |
7 |
Correct |
1966 ms |
79584 KB |
Output is correct |
8 |
Correct |
585 ms |
8412 KB |
Output is correct |
9 |
Correct |
1443 ms |
75740 KB |
Output is correct |
10 |
Correct |
533 ms |
6752 KB |
Output is correct |
11 |
Correct |
1397 ms |
75736 KB |
Output is correct |
12 |
Correct |
528 ms |
6752 KB |
Output is correct |
13 |
Correct |
1437 ms |
75740 KB |
Output is correct |
14 |
Correct |
522 ms |
6748 KB |
Output is correct |
15 |
Correct |
3859 ms |
311404 KB |
Output is correct |
16 |
Correct |
3912 ms |
312780 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
5 ms |
256 KB |
Output is correct |
2 |
Correct |
5 ms |
376 KB |
Output is correct |
3 |
Correct |
5 ms |
376 KB |
Output is correct |
4 |
Correct |
5 ms |
376 KB |
Output is correct |
5 |
Correct |
5 ms |
376 KB |
Output is correct |
6 |
Correct |
5 ms |
376 KB |
Output is correct |
7 |
Correct |
5 ms |
376 KB |
Output is correct |
8 |
Correct |
245 ms |
6760 KB |
Output is correct |
9 |
Correct |
313 ms |
6876 KB |
Output is correct |
10 |
Correct |
537 ms |
8796 KB |
Output is correct |
11 |
Correct |
1778 ms |
80220 KB |
Output is correct |
12 |
Correct |
2249 ms |
157132 KB |
Output is correct |
13 |
Correct |
1483 ms |
80044 KB |
Output is correct |
14 |
Correct |
2617 ms |
153672 KB |
Output is correct |
15 |
Correct |
2745 ms |
155200 KB |
Output is correct |
16 |
Correct |
5 ms |
376 KB |
Output is correct |
17 |
Correct |
6 ms |
504 KB |
Output is correct |
18 |
Correct |
7 ms |
760 KB |
Output is correct |
19 |
Correct |
8 ms |
760 KB |
Output is correct |
20 |
Correct |
576 ms |
8484 KB |
Output is correct |
21 |
Correct |
1872 ms |
79452 KB |
Output is correct |
22 |
Correct |
2862 ms |
156492 KB |
Output is correct |
23 |
Correct |
3823 ms |
312776 KB |
Output is correct |
24 |
Correct |
453 ms |
8920 KB |
Output is correct |
25 |
Correct |
428 ms |
7360 KB |
Output is correct |
26 |
Correct |
559 ms |
13644 KB |
Output is correct |
27 |
Correct |
3881 ms |
311376 KB |
Output is correct |
28 |
Correct |
3889 ms |
312780 KB |
Output is correct |
29 |
Correct |
7 ms |
760 KB |
Output is correct |
30 |
Correct |
7 ms |
760 KB |
Output is correct |
31 |
Correct |
6 ms |
504 KB |
Output is correct |
32 |
Correct |
6 ms |
376 KB |
Output is correct |
33 |
Correct |
4168 ms |
314992 KB |
Output is correct |
34 |
Correct |
2849 ms |
156768 KB |
Output is correct |
35 |
Correct |
1966 ms |
79584 KB |
Output is correct |
36 |
Correct |
585 ms |
8412 KB |
Output is correct |
37 |
Correct |
1443 ms |
75740 KB |
Output is correct |
38 |
Correct |
533 ms |
6752 KB |
Output is correct |
39 |
Correct |
1397 ms |
75736 KB |
Output is correct |
40 |
Correct |
528 ms |
6752 KB |
Output is correct |
41 |
Correct |
1437 ms |
75740 KB |
Output is correct |
42 |
Correct |
522 ms |
6748 KB |
Output is correct |
43 |
Correct |
3859 ms |
311404 KB |
Output is correct |
44 |
Correct |
3912 ms |
312780 KB |
Output is correct |
45 |
Correct |
147 ms |
3792 KB |
Output is correct |
46 |
Correct |
455 ms |
6916 KB |
Output is correct |
47 |
Correct |
1469 ms |
76252 KB |
Output is correct |
48 |
Correct |
2753 ms |
156636 KB |
Output is correct |
49 |
Correct |
563 ms |
9676 KB |
Output is correct |
50 |
Correct |
534 ms |
7616 KB |
Output is correct |
51 |
Correct |
651 ms |
14004 KB |
Output is correct |
52 |
Correct |
1063 ms |
77504 KB |
Output is correct |
53 |
Correct |
1028 ms |
77512 KB |
Output is correct |
54 |
Correct |
1036 ms |
77504 KB |
Output is correct |