codeforces 703d

本文探讨了在给定区间的数字中,找到出现偶数次的数字的异或和的算法实现。通过构建前缀异或和数组,并结合线段树数据结构,实现了高效的查询操作。文章详细介绍了算法步骤,包括初始化前缀异或和,处理查询请求,以及更新线段树节点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

区间[l,r]出现偶数次数的数字的异或和

a[i]<1e9;l,r,q<1e6;

由 x xor x=0;a xor 0=a;

1.区间直接异或和 为出现奇数次的数异或和

2.区间内所有不同数的或和

1异或2就是出现偶数次数的异或和。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=4E6+777;
 4 const int M=1e6+77;
 5 long long s[M];
 6 long long v[N],a[N],dv,ql,qr;
 7 struct re{
 8     long long r;
 9     long long l;
10     int id;
11 }q[M];
12 bool cmp(re x,re y){
13     return x.r<y.r||(x.r==y.r&&x.l<y.l);}
14 long long m,n;int ans[M];
15 long long az,j;
16 map<int,int>ha;
17 void mk(int o,int l,int r){
18     if(l==r&&l==az){v[o]^=dv;return;}
19     long long mid=(r+l)/2;
20     if(mid>=az)mk(o*2,l,mid);
21     else mk(o*2+1,mid+1,r);
22     v[o]=v[o*2]^v[o*2+1];
23 }
24 long long as;
25 void qz(int o,int l,int r){
26     if(ql<=l&&r<=qr){as^=v[o];}
27     else{long long mid=(r+l)/2;
28     if(ql<=mid)qz(o*2,l,mid);
29     if(mid<qr)qz(o*2+1,mid+1,r);}
30 }
31 int main(){
32 //    freopen("p.in","r",stdin);
33     //freopen("p.out","w",stdout);
34     ios::sync_with_stdio(0);
35     cin>>n;
36     for(int i=1;i<=n;i++)
37     {cin>>a[i];s[i]=s[i-1]^a[i];}
38     cin>>m;
39     for(int i=1;i<=m;i++){
40         q[i].id=i;    
41         cin>>q[i].l>>q[i].r;
42     }
43     sort(q+1,q+1+m,cmp);
44     j=1;
45     for(int i=1;i<=n;i++){    
46         dv=a[i];
47         az=i;
48         mk(1,1,n);
49         if(ha[a[i]]){az=ha[a[i]];mk(1,1,n);}
50         ha[a[i]]=i;
51         while(j<=m&&q[j].r==i){
52             as=s[i]^s[q[j].l-1];
53             ql=1;qr=i;
54             qz(1,1,n);
55             ql=1;qr=q[j].l-1;
56             if(qr>0)qz(1,1,n);
57             ans[q[j].id]=as;
58             j++;
59         }
60         
61     }
62     for(int i=1;i<=m;i++)printf("%d\n",ans[i]);
63     return 0;
64 }
View Code

 

UPD:少袄夜,戒躁

转载于:https://www.cnblogs.com/lxzl/p/9750688.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值