莫队算法

题目 http://codeforces.com/contest/617/problem/E

讲解 https://www.bilibili.com/video/av4291097

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 int const N = 100000 + 10;
 5 int const M = 1<<20;  //可能会超出范围
 6 int block;
 7 struct Node
 8 {
 9     int l,r,id;
10     bool operator < (const Node& e)const{
11         return l / block < e.l / block || l / block == e.l / block && r < e.r;
12     }
13 }q[N];
14 int n,m;
15 ll k,a[N];
16 ll Ans,ans[N],flag[M];
17 void del(int pos){
18     flag[a[pos]]--;   
19     Ans -= flag[a[pos] ^ k];
20 }
21 void add(int pos){
22     Ans += flag[a[pos] ^ k];
23     flag[a[pos]]++;
24 }
25 int main(){
26     scanf("%d%d%lld",&n,&m,&k);
27     block = (int)(ceil(pow(n,0.5)));
28     for(int i=1;i<=n;i++){
29         scanf("%lld",&a[i]);
30         a[i] = a[i-1] ^ a[i];
31     }
32     for(int i=1;i<=m;i++){
33         scanf("%d%d",&q[i].l,&q[i].r);
34         q[i].id = i;
35     }
36     sort(q+1,q+1+m);
37     int L = 1,R = 0;
38     //flag[0] = 1;
39     for(int i=1;i<=m;i++){
40         while(L < q[i].l)    del(L++);//del(L-1),    L++;    
41         while(L > q[i].l)    add(--L);//L--,    add(L-1);
42         while(R < q[i].r)    add(++R);//R++,    add(R);
43         while(R > q[i].r)    del(R--);//del(R--);
44         //ans[q[i].id] = Ans;
45         ans[q[i].id] = Ans + flag[k^a[L-1]];
46     }
47     for(int i=1;i<=m;i++)
48         printf("%lld\n",ans[i]);
49     return 0;
50 }
51 /*
52 a[l] ^ a[i+1] ^ …… ^a[r] = 
53 (a[1] ^ a[2] ^ …… ^ a[l-1]) ^ (a[1] ^ a[2] ^ …… ^a[r]) = s[l-1] ^ s[r]
54 已知区间[l,r]
55 求区间[l-1,r]为(a[1] ^ a[2] ^ …… ^ a[l-2]) ^ (a[1] ^ a[2] ^ …… ^a[r]) = s[l-2] ^ s[r]
56 s[l-2] = s[l-1] ^ 
57 */
View Code

 

 题目 https://www.luogu.org/problemnew/show/P2709

bool cmp(const node &a, const node &b){
    if(a.l/bblock!=b.l/bblock) return a.l/bblock<b.l/bblock;
    return a.r<b.r;
}
void update(int pos, int n){
    int val=arr[pos];
    if(n==1) ans=ans+2*cnt[val]+1;
    else ans=ans-2*cnt[val]+1;
    cnt[val]+=n;
}

for(int io=1; i<=k; i++){
    while(L>node[i].l) update(--L,1);
    while(R<node[i].r) update(++R,1);
    while(L<node[i].l) update(L++,-1);
    while(R>node[i].r) update(R--,-1);
    ans[node[i].id] = ans;
}
View Code

 

posted @ 2019-05-15 20:25  企鹅君  阅读(178)  评论(0编辑  收藏  举报