cf XOR and Favorite Number
2016-08-07 17:23
483 查看
现在有一个前缀异或和数组sum[],
现在我们要求区间[l,r]的异或的值,
用sum数组表示就是sum[l-1]^sum[r]==k,或者找区间中满足k^sum[r]==sum[l-1]的个数
异或:l~r之间的异或值为 sum[r]^sum[l-1]
现在我们要求区间[l,r]的异或的值,
用sum数组表示就是sum[l-1]^sum[r]==k,或者找区间中满足k^sum[r]==sum[l-1]的个数
异或:l~r之间的异或值为 sum[r]^sum[l-1]
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> using namespace std; typedef long long ll; int nn; struct node { int l,r; int id; }p[100000+10]; int pos[100000+10]; ll ans[100000+10]; ll sum[100000+10]; int num[1<<20]; ll ant; ll k; bool cmp(node a,node b) ///然后对于所有询问按照L所在块的大小排序。 { if(pos[a.l]==pos[b.l]) ///如果一样再按照R排序。 return pos[a.r]<pos[b.r]; else return pos[a.l]<pos[b.l]; } void adde(ll x) { ant+=num[k^x]; num[x]++; } void del(ll x) { num[x]--; ant-=num[k^x]; } /* 现在有一个前缀异或和数组sum[], 现在我们要求区间[l,r]的异或的值, 用sum数组表示就是sum[l-1]^sum[r]==k,或者找区间中满足k^sum[r]==sum[l-1]的个数 */ int main() { ll n,m; scanf("%I64d%I64d%I64d",&n,&m,&k); memset(num,0,sizeof(num)); nn=ceil(sqrt(n*1.0)); sum[0]=0; for(int i=1;i<=n;i++) { scanf("%I64d",&sum[i]); sum[i]=sum[i-1]^sum[i]; pos[i]=(i-1)/nn; ///分块 } for(int i=0;i<m;i++) { scanf("%I64d%I64d",&p[i].l,&p[i].r); p[i].l--;///l~r之间的异或值为sum[r]-sum[l-1],所以l-- p[i].id=i; } sort(p,p+m,cmp); int pr=0,pl=1; ant=0; for(int i=0;i<m;i++) { if(p[i].r>pr) { for(pr=pr+1;pr<=p[i].r;pr++) adde(sum[pr]); } else { for(;pr>p[i].r;pr--) del(sum[pr]); } pr=p[i].r; if(p[i].l<pl) { for(pl=pl-1;pl>=p[i].l;pl--) adde(sum[pl]); } else { for(;pl<p[i].l;pl++) del(sum[pl]); } pl=p[i].l; ans[p[i].id]=ant; } for(int i=0;i<m;i++) { printf("%I64d\n",ans[i]); } return 0; }
相关文章推荐
- tjut 2822
- mob 之 ShareSDK第三方分享
- C++中数字与字符串之间的转换
- Java的类(class)、包(package)和接口(interface)
- Spring
- spring schema自定义
- 驱动开发用到的派遣函数序号(wdm.h)
- 字符串:单词查找树
- JDBC入门
- Java 包(package)
- Linux服务-SSHD
- 字符串:字符串排序
- sys.stdout.flush()在Linux和Windows系统下的作用
- 数据结构学习笔记8——简单二叉树的实现与遍历
- Linux新手要了解的十个知识点
- 设计模式之抽象工厂模式
- 【回溯法】马拦过河卒_动态规划
- JS 数字转换为大写金额
- jqueryui 拖拽
- HDU 2571 命运