zoukankan      html  css  js  c++  java
  • codeforce617E-XOR and Favorite Number莫队+异或前缀和

    传送门:http://codeforces.com/contest/617/problem/E

    参考:https://blog.csdn.net/keyboarderqq/article/details/55807154

    题意:
    给出一系列数,对每个查询区间,计算有多少个子区间异或为k。
    思路:


    可以先预处理异或前缀,一个区间[L,R]的异或值=a[R]^a[L-1];

    其中,a为异或前缀和数组;
    如果当前区间是[A,B],加一个右端点B+1,那么这个 B+1 的贡献就是[A,B]区间内有多少个a[x] = a[B+1]^k
    那么我们可以每次记录cnt[a[x]]即cnt[a[B+1]^k],并记录cnt[a[b+1]]++,同理左区间。

    那么我们就可以使用莫队算法。

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <map>
    #include <cmath>
    using namespace std;
    typedef long long ll;
    const int maxn = 1<<20;
    
    ll a[maxn], flag[maxn];
    int pos[maxn];
    ll Ans = 0;
    ll res[maxn];
    int m,n,k;
    
    struct node {
        int l,r;
        int id;
    }Q[maxn];
    
    bool cmp(node a,node b)
    {
        if(pos[a.l]==pos[b.l])
            return a.r < b.r;
        else return pos[a.l] < pos[b.l];
    }
    
    void add(int x)
    {
        Ans += flag[a[x]^k];
        flag[a[x]]++;
    }
    
    void del(int x)
    {
        flag[a[x]]--;
        Ans -= flag[a[x]^k];
    }
    
    int main(){
        scanf("%d%d%d", &n, &m, &k);
        int sz = sqrt(n);
        for(int i=1; i<=n; i++)
        {
            scanf("%I64d", &a[i]);
            a[i] = a[i-1] ^ a[i]; 
            pos[i] = (i-1) / sz + 1;
        }
        flag[0] = 1;
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d",&Q[i].l,&Q[i].r);
            Q[i].id = i;
        }
        sort(Q+1,Q+m+1,cmp);
        int l = 1,r = 0;
        for(int i=1; i<=m; i++)
        {
            while(l < Q[i].l){
                del(l-1);
                l++;
            }
            while(l > Q[i].l){
                l--;
                add(l-1);
            }
            while(r > Q[i].r){
                del(r);
                r--;
            }
            while(r < Q[i].r){
                r++;
                add(r);
            }
            res[Q[i].id] = Ans;
        }
        for(int i=1; i<=m; i++)
        {
            printf("%I64d
    ",res[i]);
        }
        return 0;
    }
  • 相关阅读:
    查看端口有没有被占用
    微信公众号2()
    How to insert a segment of noise to music file
    puppet practice
    Docker Commands
    LempelZiv algorithm realization
    The algorithm of entropy realization
    Java network programmingguessing game
    Deploy Openstack with RDO and Change VNC console to Spice
    puppet overview
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/8945473.html
Copyright © 2011-2022 走看看