(莫队算法)CodeForces - 617E XOR and Favorite Number

题意:

长度为n的数列,m次询问,还有一个k。每次询问询问询问从数列的L到R内有多少个连续子序列异或起来等于k。

分析:

因为事先知道这题可以用莫队写,就正好用这题练习莫队。

预处理每个前缀异或和。

然后莫队按分块排序后,不断更新,用一个数组cnt[]记录当前L到R前缀和的数量。

R向右拉,新增的数量就是cnt[pre^k],pre表示当前这个R位置的前缀异或和,然后更新一下cnt。

其他的也类似。

算是一个比较好的入门题。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <cmath>
 5 #include <map>
 6 #include <vector>
 7 #include <algorithm>
 8
 9 using namespace std;
10
11 const int maxn = 1100010;
12 const int bk = 400;
13 int n, q, k;
14 struct Query {
15     int l, r, index;
16 };
17
18 Query query[maxn];
19
20 bool cmp(Query a, Query b) {
21     if(a.l / bk == b.l / bk)return a.r < b.r;
22     else return a.l / bk < b.l / bk;
23 }
24
25 long long a[maxn];
26 long long ans[maxn];
27 long long cnt[maxn];
28 long long pre[maxn];
29 long long res = 0;
30
31 void add(int x) {
32     res += cnt[x ^ k];
33     cnt[x]++;
34 }
35
36 void del(int x) {
37     cnt[x]--;
38     res -= cnt[x ^ k];
39 }
40
41 int main() {
42     scanf("%d%d%d", &n, &q, &k);
43     cnt[0] = 1;
44     pre[0] = 0;
45     for(int i = 1; i <= n; i++) {
46         scanf("%lld", &a[i]);
47         pre[i] = pre[i - 1] ^ a[i];
48     }
49     for(int i = 0; i < q; i++) {
50         scanf("%d%d", &query[i].l, &query[i].r);
51         query[i].index = i;
52     }
53     sort(query, query + q, cmp);
54     int left = 1, right = 0;
55     for(int i = 0; i < q; i++) {
56         if(right < query[i].r) {
57             for(int j = right + 1; j <= query[i].r; j++) {
58                 add(pre[j]);
59             }
60         } else {
61             for(int j = right; j > query[i].r; j--) {
62                 del(pre[j]);
63             }
64         }
65         right = query[i].r;
66         if(left < query[i].l) {
67             for(int j = left; j < query[i].l; j++) {
68                 del(pre[j - 1]);
69             }
70
71         } else {
72             for(int j = left - 1; j >= query[i].l; j--) {
73                 add(pre[j - 1]);
74             }
75         }
76         left = query[i].l;
77         ans[query[i].index] = res;
78     }
79     for(int i = 0; i < q; i++) {
80         printf("%lld\n", ans[i]);
81     }
82
83
84     return 0;
85 }
时间: 2024-10-12 11:10:14

(莫队算法)CodeForces - 617E XOR and Favorite Number的相关文章

CodeForces 617E XOR and Favorite Number

莫队算法. #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int maxn=100000+10; int a[maxn],pre[maxn]; long long cnt[20*maxn]; int pos[maxn]; int n,m,k; long long ans[maxn]; long long Ans

CodeForces - 617E XOR and Favorite Number (莫队+前缀和)

Bob has a favorite number k and ai of length n. Now he asks you to answer m queries. Each query is given by a pair li and ri and asks you to count the number of pairs of integers i and j, such that l ≤ i ≤ j ≤ r and the xor of the numbers ai, ai + 1,

codeforces 617 E. XOR and Favorite Number(莫队算法)

题目链接: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]. 详细的莫队可以百度学一

Codeforces Round #340 (Div. 2) E. XOR and Favorite Number 【莫队算法 + 异或和前缀和的巧妙】

任意门:http://codeforces.com/problemset/problem/617/E E. XOR and Favorite Number time limit per test 4 seconds memory limit per test 256 megabytes input standard input output standard output Bob has a favorite number k and ai of length n. Now he asks yo

CodeForces - 86D 莫队算法

http://codeforces.com/problemset/problem/86/D 莫队算法就是调整查询的顺序,然后暴力求解. 每回可以通过现有区间解ans(l,r)得到区间(l+1,r),(l-1,r),(l,r+1),(l,r-1)的区间解. 调整方式http://blog.csdn.net/bossup/article/details/39236275 这题比那个还要简单,查询的是K^2*Z,很清楚就是莫队算法,然而做的时候没有学过,回来补题补到 关键是我一直没明白为什么重载小于号

XOR and Favorite Number(莫队算法+分块)

E. XOR and Favorite Number time limit per test 4 seconds memory limit per test 256 megabytes input standard input output standard output Bob has a favorite number k and ai of length n. Now he asks you to answer m queries. Each query is given by a pai

CodeFroce Round 340 div2 E XOR and Favorite Number【莫队算法】

题面: Bob has a favorite number k and ai of length n. Now he asks you to answer m queries. Each query is given by a pair li and ri and asks you to count the number of pairs of integers i and j, such that l?≤?i?≤?j?≤?r and the xor of the numbers ai,?ai?

[莫队算法 线段树 斐波那契 暴力] Codeforces 633H Fibonacci-ish II

题目大意:给出一个长度为n的数列a. 对于一个询问lj和rj.将a[lj]到a[rj]从小到大排序后并去重.设得到的新数列为b,长度为k,求F1*b1+F2*b2+F3*b3+...+Fk*bk.当中F为斐波那契数列.F1=F2=1.对每一个询问输出答案模m. 区间查询离线 用莫队算法 开棵权值线段树,然后用斐波那契的性质update F(n+m)=F(n+1)*F(m)+F(n)*F(m-1); #include<cstdio> #include<cstdlib> #includ

莫队算法小结(Markdown版)

wtf,最近挖坑有点小多啊,没办法>_<容我先把糖果公园A了再来写这个吧= =看看今天能不能A掉 好吧,我承认我第二天才把糖果公园A掉>_<下面把这篇小结补上 首先众所周知的是莫队算法是要把询问先按左端点属于的块排序,再按右端点排序 复杂度就先不证了,有兴趣的同学可以自己YY下或者查阅资料 下面举几个例子详细说明 1.小Z的袜子 Description: 给定一个序列m个询问 每次询问: 区间中选两个数,两个数相等的概率 若概率为0则输出01 仔细观察发现,令x表示x这个值出现的次