P4462 [CQOI2018]异或序列
[CQOI2018]异或序列
题目描述
已知一个长度为n的整数数列
对于30%的数据,
对于100%的数据,
分析
我们都学过的
Code:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define Ld long double
const int N=2e6;
LL n,m,a[N],sq,l=1,r=0,now,ans[N],xo[N],la,k,cnt[N];//cnt为此时区间内以i为异或值的区间数
struct node{
LL l,r,id,bel;
}t[N];
inline LL read(){
LL s=0,w=1;char ch;
ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-'){w=-1;}ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
return s*w;
}
void print(LL x){
char F[200];LL cnt=0;
if(x<0) {x=-x;putchar('-');}
if(x==0){putchar('0');putchar('\n');return ;}
while(x){F[++cnt]=x%10;x/=10;}
while(cnt){putchar(F[cnt--]+'0');}
putchar('\n');
return ;
}
bool cmp(node a, node b){
return (a.bel^b.bel)?a.bel<b.bel:((a.bel&1)?a.r<b.r:a.r>b.r);
}
void del(LL pos){
--cnt[xo[pos]];//因为这个点要删了,所以区间内以此异或值结尾的区间数减1
now-=cnt[xo[pos]^k];
return ;
}
/*关于为什么del要先减再算答案
因为当k=0时,他自己也算进去了所以要先减
add同理
*/
void add(LL pos){
now+=cnt[xo[pos]^k];
cnt[xo[pos]]++;
return ;
}
int main(){
n=read(),m=read(),k=read();
sq=sqrt(n);
for(int i=1;i<=n;i++){
xo[i]=read();
xo[i]=xo[i-1]^xo[i];
}
for(int i=1;i<=m;i++){
t[i].l=read()-1;
t[i].r=read();
t[i].id=i;
t[i].bel=(t[i].l-1)/sq+1;
}
sort(t+1,t+1+m,cmp);
for(int i=1;i<=m;i++){
LL lt=t[i].l,rt=t[i].r;
while(l<lt) del(l++);
while(l>lt) add(--l);
while(r<rt) add(++r);
while(r>rt) del(r--);
ans[t[i].id]=now;
}
for(int i=1;i<=m;i++){
print(ans[i]);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】