rt,感觉自己码风还行,调了半天也不知道哪里错了。代码思路是线段树,和主流的做法差不多。
// P2574 XOR的艺术
#include<cstdio>
#define lson (id << 1)
#define rson (id << 1 | 1)
typedef long long ll;
const int MAXN = 2e5 + 10;
int n, m, val[MAXN];
struct segment_tree
{
int l, r, len, lazy, sum;
// sum:l到r的区间中 1 的数量
}t[MAXN << 2];
void update(int id)
{
t[id].sum = (t[lson].lazy ? (t[lson].len - t[lson].sum) : t[lson].sum) +
(t[rson].lazy ? (t[rson].len - t[rson].sum) : t[rson].sum);
}
void pushdown(int id)
{
if(t[id].lazy)
{
t[id].sum = t[id].len - t[id].sum;
t[lson].lazy ^= 1;
t[rson].lazy ^= 1;
t[id].lazy = 0;
}
}
void build(int id, int l, int r)
{
t[id].l = l, t[id].r = r;
t[id].len = t[id].r - t[id].l + 1;
if(l == r)
{
t[id].sum = val[id];
return;
}
int mid = (l + r) >> 1;
build(lson, l, mid);
build(rson, mid + 1, r);
update(id);
}
void change(int id, int l, int r)
{
// printf("In change:id = %d, L = %d, R = %d\n", id, l, r);
if(l == t[id].l && r == t[id].r)
{
t[id].lazy ^= 1;
return;
}
pushdown(id);
if(r <= t[lson].r) change(lson, l, r);
else if(l >= t[rson].l) change(rson, l, r);
else
{
change(lson, l, t[lson].r);
change(rson, t[rson].l, r);
}
update(id);
}
int query(int id, int l, int r)
{
// printf("In query:id = %d, L = %d, R = %d\n", id, l, r);
if(l == t[id].l && r == t[id].r) return t[id].lazy ? (t[id].len - t[id].sum) : t[id].sum;
pushdown(id);
if(r <= t[lson].r) return query(lson, l, r);
else if(l >= t[rson].l) return query(rson, l, r);
else return query(lson, l, t[lson].r) + query(rson, t[rson].l, r);
update(id);
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%1d", &val[i]);
build(1, 1, n);
for(int i = 1, op, x, y; i <= m; i++)
{
scanf("%d%d%d" ,&op, &x, &y);
if(op == 0) change(1, x, y);
else if(op == 1) printf("%d\n", query(1, x, y));
else printf("I AK IOI\n");
}
return 0;
}