题意
Description
新年将至,YY准备挂一排彩灯,已知彩灯刚挂完的彩灯共有N盏(编号为1,2,3,……),并且都是灭的。彩灯的闪烁由一段程序控制。
每一秒钟程序会生成两个正整数a和b(1<=a,b<=N),然后将编号为a和b之间的所有灯的状态改变一次,即如果灯i是灭的,那么经过一次改变,灯i会亮,如果灯i是亮的,经过一次改变,灯i会灭。
当YY看着自己挂的彩灯不断闪烁的时候,问题来了,YY想知道任意时刻某一区间灯的状态。
Input
多组测试数据,每一组第一行是一个整数N(1<=N<=1000000)和一个整数M(1<=M<=3000)。
然后是M行数据,包括以下两种形式:
1 a b 表示灯a和灯b之间的灯(含灯a和灯b)变换一次状态。
0 x y 表示YY想知道此刻灯x到灯y(包含灯x和灯y)的状态.
Output
对于每次YY想知道结果的时候,输出一行灯的状态(编号小的灯优先),如果是亮的输出”1”,否则输出”0”;
Sample Input
3 3 1 1 2 1 2 3 0 1 3
Sample Output
101
分析
就是个树状数组&&差分
每当对一个区间[l,r]进行修改,只需要进行add(l,x)和add(r+1,-x) 因为要把没有修改的区间抵消
对于每次查询直接for求每一个位置的前缀和,就会得到该位置改变了多少次,奇数次就是1,偶数次就是0
代码
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int N=1e6+10;
int a[N];
int n,m;
void add(int i,int x)
{ int h=i;
while(h<=n){
a[h]+=x;
h+=h&-h;
}
}
void range_update(int l,int r,int x){
add(l,x);
add(r+1,-x);
}
int getqsum(int x){//对某个等操作的次数
int sum=0;
while(x){
sum+=a[x];
x-=x&-x;
}
return sum;
}
int main(){
int l,r,op;
//freopen("in.txt","r",stdin);
while(cin>>n>>m){
memset(a,0,sizeof(a));
while(m--){
cin>>op>>l>>r;
if(l>r) swap(l,r);
if(op==1){
range_update(l,r,1);
}
else{
for(int i=l;i<=r;i++)
cout<<getqsum(i)<<endl;
}
}
cout<<endl;
}
return 0;
}