做法:我们考虑前缀异或和,修改操作就变成了区间[i,n]都异或x

查询操作就变成了:区间[1,x]中有几个k

显然的分块,每个块打一个tag标记表示这个块中所有的元素都异或了tag[x]

然后处理出这个块中每种数的个数

注意查询的时候零散的块要下放标记

代码:

#include<bits/stdc++.h>
#define N 100005
#define M 334
using namespace std;
int cnt[M][N*14],sum[N],tag[M],ll[M],rr[M],a[N];
int n,Q,opt,x,y,block,num;
inline int gt(int x){return (x-1)/block+1;}
inline void pushdown(int x){
if (!tag[x]) return;
for (int i=ll[x];i<=rr[x];i++){
cnt[x][sum[i]]--;
sum[i]^=tag[x];
cnt[x][sum[i]]++;
}
tag[x]=0;
}
inline void query(int x,int y,int k){
//printf("%d %d\n",gt(x),gt(y));
int ans=0;
pushdown(gt(x));pushdown(gt(y));
if (gt(x)+1>=gt(y)){
for (int i=x;i<=y;i++) if (sum[i]==k) ans++;
}
else {
for (int i=x;i<=rr[gt(x)];i++) if (sum[i]==k) ans++;
for (int i=ll[gt(y)];i<=y;i++) if (sum[i]==k) ans++;
for (int j=gt(x)+1;j<gt(y);j++) ans+=cnt[j][k^tag[j]];
}
printf("%d\n",ans);
}
inline void change(int x,int y,int z){
int tmp=z;z=z^a[x];a[x]=tmp;
if (gt(x)+1>=gt(y)){
for (int i=x;i<=y;i++){
cnt[gt(i)][sum[i]]--;
sum[i]^=z;
cnt[gt(i)][sum[i]]++;
}
}
else {
for (int i=x;i<=rr[gt(x)];i++){
cnt[gt(i)][sum[i]]--;
sum[i]^=z;
cnt[gt(i)][sum[i]]++;
}
for (int i=ll[gt(y)];i<=y;i++){
cnt[gt(i)][sum[i]]--;
sum[i]^=z;
cnt[gt(i)][sum[i]]++;
}
for (int j=gt(x)+1;j<gt(y);j++) tag[j]^=z;
}
//for (int i=1;i<=n;i++) printf("%d %d\n",sum[i],tag[i]);
}
int main(){
scanf("%d%d",&n,&Q);
for (int i=1;i<=n;i++) scanf("%d",&a[i]),sum[i]=sum[i-1]^a[i];
block=(int)sqrt(n);num=n/block;if (n%block) num++;
for (int i=1;i<=num;i++) ll[i]=(i-1)*block+1,rr[i]=i*block;rr[num]=n;
//for (int i=1;i<=num;i++) printf("%d %d\n",ll[i],rr[i]);
for (int i=1;i<=num;i++)
for (int j=ll[i];j<=rr[i];j++) cnt[i][sum[j]]++;
while (Q--){
scanf("%d%d%d",&opt,&x,&y);
if (opt==2) query(1,x,y);
else change(x,n,y);
}
return 0;
}

  

  1. #include<bits/stdc++.h>
  2. #define N 100005
  3. #define M 334
  4. using namespace std;
  5. int cnt[M][N*14],sum[N],tag[M],ll[M],rr[M],a[N];
  6. int n,Q,opt,x,y,block,num;
  7. inline int gt(int x){return (x-1)/block+1;}
  8. inline void pushdown(int x){
  9. if (!tag[x]) return;
  10. for (int i=ll[x];i<=rr[x];i++){
  11. cnt[x][sum[i]]--;
  12. sum[i]^=tag[x];
  13. cnt[x][sum[i]]++;
  14. }
  15. tag[x]=0;
  16. }
  17. inline void query(int x,int y,int k){
  18. //printf("%d %d\n",gt(x),gt(y));
  19. int ans=0;
  20. pushdown(gt(x));pushdown(gt(y));
  21. if (gt(x)+1>=gt(y)){
  22. for (int i=x;i<=y;i++) if (sum[i]==k) ans++;
  23. }
  24. else {
  25. for (int i=x;i<=rr[gt(x)];i++) if (sum[i]==k) ans++;
  26. for (int i=ll[gt(y)];i<=y;i++) if (sum[i]==k) ans++;
  27. for (int j=gt(x)+1;j<gt(y);j++) ans+=cnt[j][k^tag[j]];
  28. }
  29. printf("%d\n",ans);
  30. }
  31. inline void change(int x,int y,int z){//[x,y]����^z
  32. int tmp=z;z=z^a[x];a[x]=tmp;
  33. if (gt(x)+1>=gt(y)){
  34. for (int i=x;i<=y;i++){
  35. cnt[gt(i)][sum[i]]--;
  36. sum[i]^=z;
  37. cnt[gt(i)][sum[i]]++;
  38. }
  39. }
  40. else {
  41. for (int i=x;i<=rr[gt(x)];i++){
  42. cnt[gt(i)][sum[i]]--;
  43. sum[i]^=z;
  44. cnt[gt(i)][sum[i]]++;
  45. }
  46. for (int i=ll[gt(y)];i<=y;i++){
  47. cnt[gt(i)][sum[i]]--;
  48. sum[i]^=z;
  49. cnt[gt(i)][sum[i]]++;
  50. }
  51. for (int j=gt(x)+1;j<gt(y);j++) tag[j]^=z;
  52. }
  53. //for (int i=1;i<=n;i++) printf("%d %d\n",sum[i],tag[i]);
  54. }
  55. int main(){
  56. scanf("%d%d",&n,&Q);
  57. for (int i=1;i<=n;i++) scanf("%d",&a[i]),sum[i]=sum[i-1]^a[i];
  58. block=(int)sqrt(n);num=n/block;if (n%block) num++;
  59. for (int i=1;i<=num;i++) ll[i]=(i-1)*block+1,rr[i]=i*block;rr[num]=n;
  60. //for (int i=1;i<=num;i++) printf("%d %d\n",ll[i],rr[i]);
  61. for (int i=1;i<=num;i++)
  62. for (int j=ll[i];j<=rr[i];j++) cnt[i][sum[j]]++;
  63. while (Q--){
  64. scanf("%d%d%d",&opt,&x,&y);
  65. if (opt==2) query(1,x,y);
  66. else change(x,n,y);
  67. }
  68. return 0;
  69. }

codechef Chef And Easy Xor Queries的更多相关文章

  1. CF&&CC百套计划2 CodeChef December Challenge 2017 Chef And Easy Xor Queries

    https://www.codechef.com/DEC17/problems/CHEFEXQ 题意: 位置i的数改为k 询问区间[1,i]内有多少个前缀的异或和为k 分块 sum[i][j] 表示第 ...

  2. [CC-XXOR]Chef and Easy Problem

    [CC-XXOR]Chef and Easy Problem 题目大意: 给你一个长度为\(n(n\le10^5)\)的序列\(A(A_i<2^{31})\).\(m(m\le10^5)\)次询 ...

  3. Codeforces Round #440 (Div. 2, based on Technocup 2018 Elimination Round 2) D. Something with XOR Queries

    地址:http://codeforces.com/contest/872/problem/D 题目: D. Something with XOR Queries time limit per test ...

  4. XOR Queries(莫队+trie)

    题目链接: XOR Queries 给出一个长度为nn的数组CC,回答mm个形式为(L, R, A, B)(L,R,A,B)的询问,含义为存在多少个不同的数组下标k \in [L, R]k∈[L,R] ...

  5. XOR Queries

    XOR Queries 时间限制: 1000ms   内存限制: 256M 描述 给出一个长度为n的数组C,回答m个形式为(L,R,A,B)的询问,含义为存在多少个不同的数组下标k∈[L,R]满足C[ ...

  6. CodeChef:Chef and Problems(分块)

    CodeChef:Chef and Problems 题目大意 有一个长度为n的序列$a_1,a_2,……,a_n$,每次给出一个区间[l,r],求在区间内两个相等的数的最远距离($max(j-i,满 ...

  7. CODECHEF Chef and Churus 解题报告

    [CODECHEF]Chef and Churus Description 有一个长度为\(n\)的数组\(A\),有\(n\)个函数,第\(i\)个函数的值为\(\sum_{j=l_i}^{r_i} ...

  8. codechef Chef and The Right Triangles 题解

    Chef and The Right Triangles The Chef is given a list of N triangles. Each triangle is identfied by ...

  9. 【CodeChef PREFIXOR】Prefix XOR

    https://odzkskevi.qnssl.com/f0fbdb108ec813b1294f8f714805963b?v=1502083692 网上搜到的题解: http://blog.csdn. ...

随机推荐

  1. Linux之使用网络

    Linux有好多命令可以让你方便的使用网络,常见的有ssh,rsync,wget,curl等等,但是telnet等方式并不适用于网络交互的使用,因为它会暴露你的用户名密码等.所以一般使用安全的命令来进 ...

  2. Android万能适配器Adapter-android学习之旅(74)

    万能适配器的代码的github地址是https://github.com/fengsehng/CommonAdapter 万能适配器的代码的github地址是https://github.com/fe ...

  3. UIController子类控件&nbsp;UI_06

    1.UIImageView  是用来显示图片的控件,相当于相框,用来显示UIImage对象                //初始化UIImage对象及为其加载图片 //第一种方式 //    UII ...

  4. naoting

    生活就像一锅菠菜汤 20160714 夜

  5. Linux 学习笔记_12_文件共享服务_3_NFS网络文件服务

    NFS网络文件服务 NFS---- Network File System 用于UNIX/Linux[UNIX类操作系统]系统间通过网络进行文件共享,用户可以把网络中NFS服务器提供的共享目录挂载到本 ...

  6. 三层登录实例VB.NET版详解---理论加实战篇

    层,百度百科这样解释,首先-重叠起来的东西:重叠起来的东西中的一部分:层次|表层|大气层.其次-重叠:重复:层峦叠嶂|层出不穷.最后-量词,用于可以分出层次的事物,女孩儿强烈的第六感,三层中的层一定是 ...

  7. Linux Shell 只列出目录的方法

    在实际应用中,我们有时需要仅列出目录,下面是 4 种不同的方法. 1. 利用 ls 命令的 -d 选项: $ ls -d */ Desktop/ pic/ shell/ src/ 2. 利用 ls 命 ...

  8. Dynamics CRM 2011/2013 DeveloperToolkit的使用

    Dynamic CRM 2011的SDK中提供了一个叫DeveloperToolkit的工具,他的用途官方说明说的很明确,能方便开发者在VS中直接部署webresource.plugin.workfl ...

  9. Linux C OSS音频编程

    在linux下也可以写一个类似麦克风和喇叭这样的应用程序,只要打开/dev/dsp这个设备驱动,对该设备read读操作相当于录音,对这个设备write写操作相当于放音. 对于以下出现的一些参数我就不多 ...

  10. 集群通信组件tribes之通道拦截器

    拦截器应该可以说是一个很经典的设计模式,它有点类似于过滤器,当某信息从一个地方流向目的地的过程中,可能需要统一对信息进行处理,如果考虑到系统的可扩展性和灵活性通常就会使用拦截器模式,它就像一个个关卡被 ...