题目大意:给定一串二进制字符串,有两种操作,一种是查询第i个元素是什么,还有一个是将一个区间内所有元素转化(0->1,1->0);
题目解析:看到区间加查询,肯定线段树了,记录当前转化过几次即可;
AC代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#define PI acos(-1.0);
using namespace std;
const int maxn=10010;
int sd[400100],sx[400010];
void pushdown(int n)
{
if(sd[n]==0) return;
sx[n<<1]+=sd[n];
sx[n<<1|1]+=sd[n];
sd[n<<1]+=sd[n];
sd[n<<1|1]+=sd[n];
sd[n]=0;
}
void update(int p,int d,int l,int r,int n)
{
if(p<=l&&d>=r)
{
sx[n]++;
sd[n]++;
return ;
}
if(sd[n]) pushdown(n);
int mid=(l+r)>>1;
if(p<=mid) update(p,d,l,mid,n<<1);
if(d>mid) update(p,d,mid+1,r,n<<1|1);
}
int quary(int p,int d,int l,int r,int n)
{
if(p==l&&d==r) return sx[n];
int m=(l+r)/2;
pushdown(n);
if(p<=m) return quary(p,d,l,m,n<<1);
if(d>m) return quary(p,d,m+1,r,n<<1|1);
return 0;
}
int main()
{
int cas,c,index[10010],i,j,n;
char s[100010],ss[20];
scanf("%d",&cas);
for(c=1;c<=cas;c++)
{
scanf("%s",&s[1]);
printf("Case %d:\n",c);
int len=strlen(s+1);
memset(sx,0,sizeof(sx));
memset(sd,0,sizeof(sd));
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%s",&ss[1]);
if(ss[1]=='Q')
{
int t,a;
scanf("%d",&t);
a=quary(t,t,1,len,1);
a+=s[t]-'0';
printf("%d\n",a%2);
}
else
{
int a,b;
scanf("%d%d",&a,&b);
update(a,b,1,len,1);
}
}
}
return 0;
}