CF703D Mishka and Interesting sum(求区间出现次数偶数次数的异或和)
Posted 昵称很长很长真是太好了
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF703D Mishka and Interesting sum(求区间出现次数偶数次数的异或和)相关的知识,希望对你有一定的参考价值。
题意: 给定 n 个数的序列 a。m 次操作。操作有一种:
求
a
l
到
a
r
a_l到a_r
al到ar 中,出现偶数次的数的异或和。
n , q < = 1 e 6 , a [ i ] < = 1 e 9 n,q<=1e6, a[i]<=1e9 n,q<=1e6,a[i]<=1e9
题解: 因为本题求得是出现次数为偶数次数的异或和,我们可以知道,两个相同的数异或和为0,那么区间l-r之间的异或和即为出现次数为奇数个数数的异或和,这样我们再求一下区间l-r中不同数的异或和(树状数组老套路),用着两个异或和既可以求出答案。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int c[maxn],cc[maxn];
int a[maxn];
int lowbit(int x){
return x&(-x);
}
struct edge{
int l,r,id;
bool operator<(const edge & a)const{
return r<a.r;
}
}pp[maxn];
int n;
void update1(int i,int x){
while(i<=n){
c[i]^=x;
i+=lowbit(i);
}
}
int query1(int i){
int res=0;
while(i>0){
res^=c[i];
i-=lowbit(i);
}
return res;
}
int ans[maxn],b[maxn],pos[maxn];
int pre[maxn];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
int q;
scanf("%d",&q);
for(int i=1;i<=q;i++){
//int l,r;
scanf("%d %d",&pp[i].l,&pp[i].r);
pp[i].id=i;
}
sort(pp+1,pp+1+q);
sort(b+1,b+1+n);
int m=unique(b+1,b+1+n)-b-1;
int posnow=1;
for(int i=1;i<=n;i++){
int xxx=lower_bound(b+1,b+m+1,a[i])-b;
if(pos[xxx]==0){
update1(i,a[i]);
}
else{
update1(pos[xxx],a[i]);
update1(i,a[i]);
}
pos[xxx]=i;
pre[i]=pre[i-1]^a[i];
while(pp[posnow].r==i){
//cout<<posnow<<endl;
int x=query1(pp[posnow].r)^query1(pp[posnow].l-1);
int y=pre[pp[posnow].r]^pre[pp[posnow].l-1];
ans[pp[posnow].id]=x^y;
//cout<<"debug "<<x<<" "<<y<<endl;
posnow++;
}
//cout<<x^y<<endl;
}
for(int i=1;i<=q;i++){
printf("%d\\n",ans[i]);
}
}
以上是关于CF703D Mishka and Interesting sum(求区间出现次数偶数次数的异或和)的主要内容,如果未能解决你的问题,请参考以下文章
CF703D Mishka and Interesting sum
[CF 703D]Mishka and Interesting sum
CF703D Mishka and Interesting sum
CF703D Mishka and Interesting sum(求区间出现次数偶数次数的异或和)