【luogu P4462 [CQOI2018]异或序列】 题解

题目链接:https://www.luogu.org/problemnew/show/P4462

ax+ax-1+...+ay = cntx+cnty 这样把一段序列变成两段相加跑莫队。

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cmath>
 5 using namespace std;
 6 const int maxn = 200010;
 7 int curR = 0, curL = 1, answer,a[maxn], ans[maxn], cnt[maxn], n, m, k, bl;
 8 struct query{
 9     int l,r,p;
10 }q[maxn];
11 
12 bool cmp(const query &a, const query &b)
13 {
14     return (a.l/bl) == (b.l/bl) ? a.r<b.r : a.l<b.l;
15 }
16 
17 inline void add(int pos)
18 {
19     cnt[a[pos]]++;
20     answer+=cnt[a[pos]^k];
21 }
22 
23 inline void remove(int pos)
24 {
25     cnt[a[pos]]--;
26     answer-=cnt[a[pos]^k];
27 }
28 
29 int main()
30 {
31     scanf("%d%d%d",&n,&m,&k);
32     bl = sqrt(n);
33     cnt[0] = 1;
34     for(int i = 1; i <= n; i++)
35     {
36         scanf("%d",&a[i]);
37         a[i] ^= a[i-1]; 
38     }
39     
40     for(int i = 1; i <= m; i++)
41     {
42         scanf("%d%d",&q[i].l,&q[i].r);
43         q[i].p = i;
44     }
45     
46     sort(q+1,q+1+m,cmp);
47     
48     for(int i = 1; i <= m; i++)
49     {
50         while(curL < q[i].l) remove(curL-1),curL++;
51         while(curL > q[i].l) curL--,add(curL-1);
52         while(curR < q[i].r) add(++curR);
53         while(curR > q[i].r) remove(curR--);
54         ans[q[i].p] = answer;
55     }
56     for(int i = 1; i <= m; i++)
57     printf("%d\n",ans[i]);
58     return 0;
59 }

 

posted @ 2018-04-22 20:45  Misaka_Azusa  阅读(197)  评论(0编辑  收藏  举报
Live2D