您的位置:首页 > 其它

bzoj1230[Usaco2008 Nov]&&[TJOI2009]开关灯(线段树)

2017-08-12 12:08 507 查看
TJ的省选题居然是USACO月赛原题。。。我果然是在弱省,给跪了。

线段树维护区间修改和区间查询。

#include <bits/stdc++.h>
#define N 100010
int n,m;
struct node{
int x,lazy;//--number of 0
}tree[N<<2];
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;char ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline
4000
void build(int p,int l,int r){
tree[p].x=tree[p].lazy=0;
if(l==r) return;
int mid=l+r>>1;
build(p<<1,l,mid);build(p<<1|1,mid+1,r);
}
inline void pushup(int p){
tree[p].x=tree[p<<1].x+tree[p<<1|1].x;
}
inline void pushdown(int p,int l,int r){
if(!tree[p].lazy) return;int mid=l+r>>1;
tree[p<<1].lazy^=1;tree[p<<1|1].lazy^=1;
tree[p<<1].x=mid-l+1-tree[p<<1].x;tree[p<<1|1].x=r-mid-tree[p<<1|1].x;
tree[p].lazy=0;
}
inline void change(int p,int l,int r,int x,int y){
if(x<=l&&r<=y){
tree[p].lazy^=1;tree[p].x=r-l+1-tree[p].x;return;
}
pushdown(p,l,r);int mid=l+r>>1;
if(x<=mid) change(p<<1,l,mid,x,y);
if(y>mid) change(p<<1|1,mid+1,r,x,y);
pushup(p);
}
inline int query(int p,int l,int r,int x,int y){
if(x<=l&&r<=y) return tree[p].x;
int mid=l+r>>1,res=0;pushdown(p,l,r);
if(x<=mid) res+=query(p<<1,l,mid,x,y);
if(y>mid) res+=query(p<<1|1,mid+1,r,x,y);
return res;
}
int main(){
//  freopen("a.in","r",stdin);
n=read();m=read();build(1,1,n);
while(m--){
int op=read(),x=read(),y=read();
if(op) printf("%d\n",query(1,1,n,x,y));
else change(1,1,n,x,y);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: