题目链接:http://codeforces.com/problemset/problem/617/E

题目:

  给你a1 a2 a3 ··· an 个数,m次询问:在[L, R] 里面又多少中 [l, r] 使得 al xor al+1 xor ··· ar 为 k。

题解:

  本题只有区间查询没有区间修改,而且数据量不大(10w),所以可以用离线的方法解决。

  使用莫队算法来解决,就需要O(1)的修改[L, R+1] 、[L, R-1]、[L+1, R]、[L-1, R]。

  详细的莫队可以百度学一下。

  这里讲一下怎么样通过O(1)来修改

  1)我们需要求前缀xor。

  2)[L, R] -> [L, R+1]:这里添加了一个aR+1 , 就可以通过前缀xor T,所以我们需要找 T ^ k  H 的个数(因为H^T=K-> H=T^K)。

      如果H在前面出现过,比如(全部是前缀xor)1 2 1[加入]。这时xor 为1 ,我们当k为0, 那么 0^1 = 1的个数就为1。

      这里的1的数量有什么意义。如果我们要想 1 [2 1] 这一段的xor ,是不是应该  T3(1)xor T1(1) = 0 = k;

    [L, R] -> [L, R-1] : 这里是删除了一个a, num[TaR] --, 我们要求的是 k^ TaR 的个数 。

      1 2 1 1[删除], k = 0, 0^1 = 1 , 这个有2个1。这里2个的意思 1 [2 1 1] ( T4 xor T1 = 0)和 1 2 1 [1]  (T4 xor T3 = 0),因为删去了aR 所以aR 结尾的区间就要减去。

    [L, R] -> [L-1, R] : 这个是增加多一个 aL-1  。就是在[L-1, R] 这个里面找 [L-1, r(r<R)] 使得xor 为k , 所以就需要 k^((L-1)-1)。

    [L, R] -> [L+1, R] :这里是删除了 aL 。就是在 [L, r(r<R)] 找 xor 为 k 的 。T[r]^T[L-1] = k。

      num[0] = 1 。这里是应为一开始前缀异或为0 .

 

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
using namespace std;
typedef long long LL;
#define ms(a, b) memset(a, b, sizeof(a))
#define pb push_back
#define mp make_pair
const int INF = 0x7fffffff;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+;
const int maxn = +;
int a[maxn];
LL num[];
LL x[maxn];
LL ans[maxn];
struct Point
{
int l, r, id;
}node[maxn];
int unit, n, m, k;
void init() {
ms(a, );
ms(ans, );
ms(num, );
ms(x, );
}
bool cmp(Point x1, Point x2)
{
if(x1.l/unit != x2.l/unit){
return x1.l/unit < x2.l/unit;
}
else
return x1.r < x2.r;
}
void work()
{
for(int i = ;i<=n;i++)
x[i] = x[i-]^a[i]; int L, R;
LL temp = ;
L = , R = ;
num[]++;
for(int i = ;i<m;i++){
while(R<node[i].r){
R++;
temp+=num[k^x[R]];
num[x[R]]++;
}
while(R>node[i].r){
num[x[R]]--;
temp-=num[x[R]^k];
R--;
}
while(L>node[i].l){
L--;
temp+=num[k^x[L-]];
num[x[L-]]++;
}
while(L<node[i].l){
num[x[L-]]--;
temp-=num[x[L-]^k];
L++;
}
ans[node[i].id] = temp;
}
}
void solve() {
scanf("%d%d%d", &n, &m, &k);
unit = (int)sqrt(n);
for(int i = ;i<=n;i++) scanf("%d", &a[i]);
for(int i = ;i<m;i++){
node[i].id = i;
scanf("%d%d", &node[i].l, &node[i].r);
}
sort(node, node+m, cmp);
work();
for(int i = ;i<m;i++){
printf("%lld\n", ans[i]);
}
}
int main() {
#ifdef LOCAL
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
// ios::sync_with_stdio(0);
// cin.tie(0); init();
solve(); return ;
}

最新文章

  1. Android Studio的SVN Performing VCS Refresh/Commit 长时间不结束
  2. 方法的覆盖(override)、重载(overload)和重写(overwrite)
  3. POJ 1781
  4. HDU 5592 ZYB&#39;s Premutation(树状数组+二分)
  5. Robotium--scroll操作系列
  6. J2EE 中 The function valueOf must be used with a prefix when a default namespace is not specified 错误
  7. win7+IE11 中开发工具报错occurredJSLugin.3005解决办法
  8. java 操作配置文件 .properties
  9. poj 1035 Spell checker(hash)
  10. TCP的流量控制和拥塞处理
  11. 从零学习Fluter(五):Flutter中手势滑动拖动已经网络请求
  12. 第七十九课 最短路径(Floyd)
  13. 微信小程序-配置解答
  14. iOS __weak学习碰到的疑问
  15. python匹配两个字符串中间的字符串
  16. web存储机制(localStorage和sessionStorage)
  17. 2015 UESTC 数据结构专题A题 秋实大哥与小朋友 线段树 区间更新,单点查询,离散化
  18. sample采样倾斜key并单独进行join代码
  19. Visual Studio 2017 编译Clang
  20. javascript快速入门10--运算符,语句

热门文章

  1. 【ABAP系列】SAP ABAP WS_DELIVERY_UPDATE 修改数量、过账日期并发货过账
  2. PHPstorm Xdebugger最全详细
  3. Spring MVC配置文件
  4. 红黑树的删除操作---以JDK源码为例
  5. MySQL binlog之数据恢复
  6. 靶形数独 (dfs+预处理+状态压缩)
  7. 收集慕课网讲解的border知识
  8. Handle Refresh Token Using ASP.NET Core 2.0 And JSON Web Token
  9. 时间戳位数不够13位,通过es6 的padEed补零
  10. Sersync 上配置 Sersync 服务