【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 }
隐约雷鸣,阴霾天空,但盼风雨来,能留你在此。
隐约雷鸣,阴霾天空,即使天无雨,我亦留此地。