题目大意

给出一个序列\(a_1,...,a_n\)(\(a,n\leq 10^5\)),一个数\(k\)(\(k\leq 10^5\)),\(m\)(\(m\leq10^5\))次询问,每次询问给\(l,r\),求\([l,r]\)有多少个子区间\([x,y]\)满足\(a_x \bigoplus ...\bigoplus a_y=k\)

题解

求前缀异或和\(s_1,...,s_n\),询问变成对于每个\(x\in [l,r]\),总共有多少\(y\in[l-1,x)\)满足\(a_x\bigoplus a_y=k\),即询问有多少个\(y\in[l-1,x)\)满足\(a_x\bigoplus k=a_y\)

这样就会有一个暴力的想法:从\(l\)到\(r\)枚举\(x\),维护\(a_{l-1},...,a_{x-1}\)中每个值的出现次数。

发现\(k\)不变,没有修改或强制在线,就可以考虑离线。

假设当前考虑的区间是\([l_0,r_0]\),把区间变成\([l_0-1,r_0]\)时要考虑\(a_{l_0-2}\)与\(a_{l_0-1},...,a_{r_0}\)的贡献。把区间变成\([l_0+1,r_0]\)时同理。

假设当前考虑的区间是\([l_0,r_0]\),把区间变成\([l_0,r_0+1]\)时要考虑\(a_{r_0+1}\)与\(a_{l_0-1},...,a_{r_0}\)的贡献。把区间变成\([l_0,r_0-1]\)时同理。

代码
#include<algorithm>
#include<bitset>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define rep(i,x,y) for(register int i=(x);i<=(y);++i)
#define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
#define view(u,k) for(int k=fir[u];k!=-1;k=nxt[k])
#define maxn 100007
#define maxk ((1<<17)+1)
#define LL long long
using namespace std;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
return x*f;
}
void write(LL x)
{
if(x==0){putchar('0'),putchar('\n');return;}
int f=0;char ch[20];
if(x<0)putchar('-'),x=-x;
while(x)ch[++f]=x%10+'0',x/=10;
while(f)putchar(ch[f--]);
putchar('\n');
return;
}
int blo=300,num[maxk],num2[maxk],a[maxn],n,m,k;
LL ans[maxn],nowans;
struct quest{int l,r,id;}q[maxn];
bool cmp(quest x,quest y){return (x.l/blo==y.l/blo)?(x.r<y.r):(x.l<y.l);}
void addl(int id,int f)
{
if(f==1)num2[a[id]]++;
nowans+=(LL)f*num2[a[id-1]^k];
if(f==-1)num2[a[id]]--;
num[a[id-1]]+=f;
}
void addr(int id,int f)
{
if(f==1)num[a[id-1]]++;
nowans+=(LL)f*num[a[id]^k];
if(f==-1)num[a[id-1]]--;
num2[a[id]]+=f;
}
int main()
{
n=read(),m=read(),k=read();
rep(i,1,n)a[i]=a[i-1]^read();
rep(i,1,m)q[i].l=read(),q[i].r=read(),q[i].id=i;//cout<<"ookk"<<endl;
sort(q+1,q+m+1,cmp);
int nowl=1,nowr=1;num[0]++,num2[a[1]]++,nowans+=(k==a[1])?1:0;
rep(i,1,m)
{
while(nowl>q[i].l)nowl--,addl(nowl,1);
while(nowr<q[i].r)nowr++,addr(nowr,1);
while(nowl<q[i].l)addl(nowl,-1),nowl++;
while(nowr>q[i].r)addr(nowr,-1),nowr--;
ans[q[i].id]=nowans;
}
//rep(i,1,n)cout<<a[i]<<" ";cout<<endl;
//rep(i,1,n)cout<<b[i]<<" ";cout<<endl;
rep(i,1,m)write(ans[i]);
return 0;
}
一些感想

想玩飞天虫棍!!!

最新文章

  1. 第一个Java程序HelloWorld
  2. 安卓中級教程(4):ScrollView與ListView之間的高度問題
  3. [转]SQL SERVER – Find Most Expensive Queries Using DMV
  4. WP老杨解迷:如何获得更多的应用评价和解读内容刷新
  5. (WPF) 文件和文件夹选择对话框。
  6. jquery mobile最棘手的一个问题
  7. Apache配置虚拟目录和多主机头
  8. C# 封装-属性
  9. webpack - tree shaking
  10. JNI调用问题(部分机型崩溃)
  11. PHP的AES加密类
  12. Web项目中出现乱码
  13. UnicodeEncodeError: &#39;ascii&#39; codec can&#39;t encode characters in position
  14. phpstrom2018
  15. socket:10038错误
  16. JMeter常用菜单以及设置
  17. stl源码剖析 详细学习笔记 set map
  18. 安卓程序代写 网上程序代写[原]Android之Bluetooth编程
  19. 【大数据系列】Hadoop DataNode读写流程
  20. L2-2 重排链表 (25 分)

热门文章

  1. CSS高级学习-1
  2. 【Redis 向Redis中批量导入mysql中的数据(亲自测试)】
  3. 转载:在Excel中将数据库字段转换成驼峰式
  4. koa 项目实战(九)passport验证token
  5. Node安装配置
  6. [Kerberos] Kerberos教程(二)
  7. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-8.用户模块开发之保存微信用户信息
  8. Net分布式系统之七:日志采集系统(1)(转)
  9. JAVA 基础编程练习题3 【程序 3 水仙花数】
  10. pyinstaller发布exe,弹出Failed to execute script main