Codeforces 617EXOR and Favorite Number (Round #340 (Div. 2) E题) 莫队算法 + 异或基本性质
来源:互联网 发布:php开发app教程 编辑:程序博客网 时间:2024/05/21 01:28
题意
- 给你一个数组和一个数k,然后有m个查询,每次给你l,r,问你[l , r]区间内有多少对(i,j),使得a[i] ^ a[i+1] … ^ a[j] = k
思路
- pref[i]记录a[0] ^ a[1] ^ … ^a[i]的值
- 区间[l, r]的解 = 统计(i, j)使得pref[i-1] ^ pref[j] = k的个数。(因为,a ^ b ^ a = b,所以所有小于i的数被以后两次后就相当于没被异或,而i~j则被异或了一次)
- 然后,为了方便实现,我们换一种说法,相当于统计在[l-1, r]区间内有多少(i, j),使得pref[i] ^ pref[j] = k
- 当然,因为有m个查询我们不能简单的暴力求解,所以这里用到了莫队算法
- 这里给两个我自学时参考的文章:
- http://wenku.baidu.com/link?url=id9fDlyKDaAINJtr6Iq3SYY97VOvec4cdo5QazWreZX3jCNFJU-gRZEreLicE2zoYWjpY4YCe1HmwewpH8bufjeb_aivNOuWcUp0HPlZzCi
- http://blog.csdn.net/bossup/article/details/39236275
- 基本想法就是,离线算法,存储所有的查询,然后对查询进行某种方法的排序,之后暴力的去算
- 但是,这里的暴力也不太一样,是当算出了[l, r]区间的解后,左右移动l 和 r, 来算出[l’ , r’]的解
- 所以,它要求我们可以很快的从[l, r]的解算出, [l-1, r], [l+1, r], [l, r-1], [l, r+1]的解
- 这里用cnt数组来辅助,cnt[v] 表示 [l-1, r]区间内有cnt[v]个pref[i] = v的数, 然后我们就可以很快的算出刚才所述的解,具体方法,详见代码,要注意的是更新ans和cnt的顺序是有要求的,需要仔细考虑
- 最后说个坑点,cnt数组不能开小了。。。因为1e6的数异或之后可不止1e6。。我居然被这个点坑了一个上午。。。
实现
#include <bits/stdc++.h>using namespace std;const int maxn = 2e6+6;typedef long long ll;const int B = 316; //316 < sqrt(1e5)int a[maxn];int pref[maxn];struct Node{ int l,r,id;}query[maxn];int cnt[maxn];ll Ans[maxn];bool cmp(Node x, Node y){ if (x.l / B != y.l / B) return x.l < y.l; return x.r < y.r;}int main(){ int n,m,k; ios::sync_with_stdio(false); cin>>n>>m>>k; for (int i=1;i<=n;i++) { cin>>a[i]; } for (int i=1;i<=n;i++){ pref[i] = a[i] ^ pref[i-1]; } for (int i=0;i<m;i++){ int l,r; cin>>query[i].l>>query[i].r; query[i].id = i; } sort(query,query+m,cmp); //这里可以让r = 0进行初始化 int l = 0, r = 1; ll ans = a[1] == k ? 1 : 0; cnt[pref[1]]++; cnt[0]++; for (int i=0; i < m; i++){ while (l < query[i].l - 1){ cnt[pref[l]]--; ans -= (ll)cnt[pref[l] ^ k]; l++; } while (l > query[i].l - 1){ l--; ans += (ll)cnt[pref[l] ^ k]; cnt[pref[l]]++; } while (r > query[i].r){ cnt[pref[r]]--; ans -= (ll)cnt[pref[r] ^ k]; r--; } while (r < query[i].r){ r++; ans += (ll)cnt[pref[r] ^ k]; cnt[pref[r]]++; } Ans[query[i].id] = ans; } for (int i=0;i<m;i++){ cout << Ans[i] << endl; } return 0;}
1 0
- Codeforces 617EXOR and Favorite Number (Round #340 (Div. 2) E题) 莫队算法 + 异或基本性质
- Codeforces Round #340 (Div. 2) 617E XOR and Favorite Number 莫队算法
- Codeforces Round #340 (Div. 2) E. XOR and Favorite Number(莫队算法)
- Codeforces Round #340 (Div. 2)E-XOR and Favorite Number(莫队算法)
- Codeforces Round #340 (Div. 2)E-XOR and Favorite Number(莫队算法)★ ★
- Codeforces Round #340 (Div. 2) E. XOR and Favorite Number 莫队算法
- Codeforces Round #340 (Div. 2)E. XOR and Favorite Number(莫队算法)
- Codeforces Round #340 (Div. 2) E. XOR and Favorite Number —— 莫队算法
- Codeforces Round #340 (Div. 2) E XOR and Favorite Number(莫队算法)
- Codeforces Round #340 (Div. 2) E. XOR and Favorite Number【莫队算法】
- Codeforces Round #340 (Div. 2) E XOR and Favorite Number
- Codeforces Round #340 (Div. 2) E. XOR and Favorite Number
- Codeforces Round #340 (Div. 2) E. XOR and Favorite Number
- Codeforces Round #340 (Div. 2) E. XOR and Favorite Number
- Codeforces 617EXOR and Favorite Number
- 【莫队算法】[CodeForces - 617E/Round #340]XOR and Favorite Number
- 【Codeforces Round 340 (Div 2)E】【莫队算法 真实区间思想】XOR and Favorite Number m组区间询问 问区间中多少连续段异或值为k
- Codeforces 617E XOR and Favorite Number (区间异或和 莫队算法 分块暴力)
- ios自动打包(适用于批量打包)
- struts2的常用标签(二)
- java中栈内存和堆内存的区别
- 只能输入数字,不需要小数点,错误可能是
- 使用Tomcat时一次Http访问的过程
- Codeforces 617EXOR and Favorite Number (Round #340 (Div. 2) E题) 莫队算法 + 异或基本性质
- 原型模式(Prototype Pattern)
- 引导界面微场景交互设计与技术实现V2.0
- Android内存泄漏杂谈
- 多线程之NSOperation
- JNDI的作用是什么
- 如何用github上传自己的代码,解决冲突
- 18001 Farmer Cat
- 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联