思路:
- 要改变的是一个范围的情况,所以正常情况下会超时。
- 查阅后知道应该用一个叫做树状数组的结构。
注意:
- 我没怎么看懂,可能没太仔细看。
- 树状数组当中存在的是前后的差,所以每次变动只是在start,end+1变动.
- 因为一直上去的是lowbit情况,方便后面前缀和。
- 因为树状数组存放的不是本身的值,通过前缀和来求到。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int MAX=1000005;
int lan[MAX];
int n,m;
//树状数组的相关知识
int lowbit(int x){
return x&(-x);
}
//单点更新
void update(int x,int val){
for(int i=x;i<=n;i+=lowbit(i)){
lan[i]+=val;
}
}
//范围更新
void range_update(int start,int end,int val){
update(start,val);
//其中树状数组存放的是前后的差。
//在数里面修改和差为logN,没有遍历。
update(end+1,-val);
}
//前缀和
int ask(int x){
int sum=0;
for(int i=x;i;i-=lowbit(i))
sum+=lan[i];
return sum;
}
int main(){
while(~scanf("%d%d",&n,&m)){
memset(lan,0,sizeof(lan));
for(int i=0;i<m;i++){
int flag,start,end;
scanf("%d%d%d",&flag,&start,&end);
//可能出现后大,题目没有告知谁大
if(start>end) swap(start,end);
if(flag){
range_update(start,end,1);
}else{
for(int j=start;j<=end;j++){
if(ask(j)&1)cout<<1;
else cout<<0;
}
cout<<endl;
}
}
}
return 0;
}
标签:end,树状,int,1156,ZCMU,start,数组,include
From: https://www.cnblogs.com/hai-zei/p/18202597