BZOJ1230 [Usaco2008 Nov]lites 开关灯

区间not,求区间1的个数。。。线段树裸题

然而窝并不会线段树

我们可以对序列分块,每个块记录0/1的个数和tag表示又没有区间not过就好了

 1 /**************************************************************
 2     Problem: 1230
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:796 ms
 7     Memory:1608 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <cmath>
12 #include <algorithm>
13  
14 using namespace std;
15 const int N = 1e5 + 5;
16 const int SZ = 505;
17  
18 int n, m;
19 int a[N];
20 int sz, b[N], st[SZ], cnt[SZ][2], tag[SZ], cnt_block;
21  
22 inline int read() {
23     static int x;
24     static char ch;
25     x = 0, ch = getchar();
26     while (ch < '0' || '9' < ch)
27         ch = getchar();
28     while ('0' <= ch && ch <= '9') {
29         x = x * 10 + ch - '0';
30         ch = getchar();
31     }
32     return x;
33 }
34  
35 inline void pre() {
36     int i;
37     sz = sqrt(n);
38     if (!sz) sz = 1;
39     for (i = 1; i <= n; ++i) {
40         if (i % sz == 1 || sz == 1) st[++cnt_block] = i;
41         b[i] = cnt_block, ++cnt[cnt_block][0];
42     }
43     st[cnt_block + 1] = n + 1;
44 }
45  
46 inline void push_tag(int B) {
47     static int i;
48     if (!tag[B]) return;
49     for (i = st[B]; i < st[B + 1]; ++i)
50         a[i] = !a[i];
51     swap(cnt[B][0], cnt[B][1]);
52     tag[B] = 0;
53 }
54  
55 inline void change(int x, int y) {
56     static int i, t1, t2;
57     t1 = b[x], t2 = b[y];
58     for (i = t1 + 1; i < t2; ++i) tag[i] = !tag[i];
59     if (t1 == t2)
60         for (push_tag(t1), i = x; i <= y; ++i)
61             --cnt[t1][a[i]], a[i] = !a[i], ++cnt[t1][a[i]];
62     else {
63         for (push_tag(t1), i = x; i < st[t1 + 1]; ++i)
64             --cnt[t1][a[i]], a[i] = !a[i], ++cnt[t1][a[i]];
65         for (push_tag(t2), i = st[t2]; i <= y; ++i)
66             --cnt[t2][a[i]], a[i] = !a[i], ++cnt[t2][a[i]];
67     }
68 }
69  
70 inline int query(int x, int y) {
71     static int i, t1, t2, res;
72     t1 = b[x], t2 = b[y], res = 0;
73     for (i = t1 + 1; i < t2; ++i)
74         res += cnt[i][!tag[i]];
75     if (t1 == t2)
76         for (push_tag(t1), i = x; i <= y; ++i) res += a[i];
77     else {
78         for (push_tag(t1), i = x; i < st[t1 + 1]; ++i) res += a[i];
79         for (push_tag(t2), i = st[t2]; i <= y; ++i) res += a[i];
80     }
81     return res;
82 }
83  
84 int main() {
85     int i, oper, x, y;
86     n = read(), m = read();
87     pre();
88     for (i = 1; i <= m; ++i) {
89         oper = read(), x = read(), y = read();
90         if (oper == 0) change(x, y);
91         else printf("%d
", query(x, y));
92     }
93     return 0;
94 }
View Code
By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
原文地址:https://www.cnblogs.com/rausen/p/4418125.html