题目链接:点击打开链接
Time Limit: 2 second(s) | Memory Limit: 64 MB |
Given a binary number, we are about to do some operations on the number. Two types of operations can be here.
'I i j' which means invert the bit from i to j (inclusive)
'Q i' answer whether the ith bit is 0 or 1
The MSB (most significant bit) is the first bit (i.e. i=1). The binary number can contain leading zeroes.
Input
Input starts with an integer T (≤ 10), denoting the number of test cases.
Each case starts with a line containing a binary integer having length n (1 ≤ n ≤ 105). The next line will contain an integer q (1 ≤ q ≤ 50000) denoting the number of queries. Each query will be either in the form 'I i j' where i, j are integers and 1 ≤ i ≤ j ≤ n. Or the query will be in the form'Q i' where i is an integer and 1 ≤ i ≤ n.
Output
For each case, print the case number in a single line. Then for each query 'Q i' you have to print 1 or 0 depending on the ith bit.
Sample Input | Output for Sample Input |
2 0011001100 6 I 1 10 I 2 7 Q 2 Q 1 Q 7 Q 5 1011110111 6 I 1 10 I 2 7 Q 2 Q 1 Q 7 Q 5 | Case 1: 0 1 1 0 Case 2: 0 0 0 1 |
Note
Dataset is huge, use faster i/o methods.
大意:给出一行字符串,只包含 0 和 1,给出操作选项;I: 为把一个区间内字符反向 0 变为 1,1 变为 0;Q:查询第 i 个字符。
思路:用数状数组或者线段树进行维护。利用树状数组的快速区间求和维护,将每个点的反转次数进进行记录,奇数次后肯定的发生改变,偶数次就不用进行改变。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n;
char str[100010];
int c[100010];
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int y)
{
while(x<=n)
{
c[x]+=y;
x+=lowbit(x);
}
}
int Sum(int x)
{
int sum=0;
while(x)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
int t,text=0;
scanf("%d",&t);
while(t--)
{
memset(c,0,sizeof(c));
scanf("%s",str);
n=strlen(str);
int tp;
scanf("%d",&tp);
printf("Case %d:\n",++text);
while(tp--)
{
char ch[2];
scanf("%s",ch);
if(ch[0]=='I')
{
int a,b;
scanf("%d %d",&a,&b);
add(a,1);
add(b+1,-1);
}
else
{
int id;
scanf("%d",&id);
if(Sum(id)&1)
printf("%d\n",!(str[id-1]-'0'));
else
printf("%d\n",str[id-1]-'0');
}
}
}
return 0;
}