首页 > 代码库 > CSU 1258 异或运算的线段树
CSU 1258 异或运算的线段树
题目大意:
在给定区间内对每个数的最后一个二进制为1的位将其修改为0,如果数本身已经为0了,就不做改变
输出给定区间的所有数的异或值
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 #define N 10005 5 #define L ls,x,mid 6 #define R rs,mid+1,y 7 int sum[N<<2],cnt[N<<2],num[N]; 8 9 void push_up(int o)10 {11 sum[o]=sum[o<<1]^sum[o<<1|1];12 cnt[o]=cnt[o<<1]+cnt[o<<1|1];13 }14 15 void build(int o,int x,int y)16 {17 int mid=(x+y)/2,ls=o<<1,rs=o<<1|1;18 cnt[o]=0;19 if(x==y){20 if(!num[x]) cnt[o]=1;21 sum[o]=num[x];22 return;23 }24 build(L);25 build(R);26 push_up(o);27 }28 29 void update(int o,int x,int y,int s,int t)30 {31 int mid=(x+y)/2,ls=o<<1,rs=o<<1|1;32 if(cnt[o]==y-x+1) return;33 if(x==y){34 sum[o]^=sum[o]&(-sum[o]);35 if(sum[o]==0) cnt[o]=1;36 return;37 }38 if(mid>=s) update(L,s,t);39 if(mid<t) update(R,s,t);40 push_up(o);41 }42 43 int query(int o,int x,int y,int s,int t)44 {45 int mid=(x+y)/2,ls=o<<1,rs=o<<1|1;46 if(cnt[o]==y-x+1){47 return 0;48 }49 int ans=0;50 if(x>=s&&y<=t){51 return sum[o];52 }53 if(mid>=s) ans^=query(L,s,t);54 if(mid<t) ans^=query(R,s,t);55 return ans;56 }57 58 int main()59 {60 int n,m,a,b,c;61 while(~scanf("%d%d",&n,&m)){62 for(int i=1;i<=n;i++)63 scanf("%d",num+i);64 65 build(1,1,n);66 67 for(int i=0;i<m;i++){68 scanf("%d%d%d",&a,&b,&c);69 if(a==1) update(1,1,n,b,c);70 else{71 int ans=query(1,1,n,b,c);72 printf("%d\n",ans);73 }74 }75 }76 return 0;77 }
CSU 1258 异或运算的线段树
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。