zoukankan      html  css  js  c++  java
  • P4462 [CQOI2018]异或序列

    P4462 [CQOI2018]异或序列

    Problem:

      https://www.luogu.com.cn/problem/P4462

    Solution:

      求出异或前缀和sum[],对于 a[ l ] ^ a[ l + 1] ^ .... ^ a[ r ] 就变成了sum[ r ] ^ sum[ l - 1 ],所以最终我们要求的就是在区间 [ L,R ] 中有多少子区间 [ l,r ] 是满足 sum[ r ] ^ sum[ l - 1 ] = k 的(sum[ r ] ^ sum[ l - 1 ] = k 《==》sum[ l - 1 ] = sum[ r ] ^ k 《==》sum[ r ] = k ^ sum[ l - 1 ]),变换以下就是求 [ l - 1,r ] 区间有多少个数是等于k ^ sum[ x ] (ps:x 是当前区间中新加入的数) 

      因此题目就变成了区间记数问题,而题目中可以离线处理,所以我们就可以用莫队来写。

    #include<bits/stdc++.h>
    #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
    #define _for(i,s,t) for(int i=s;i<t;i++)
    #define _rof(i,s,t) for(int i=s;i>t;i--)
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define per(i,s,t) for(int i=s;i>=t;i--)
    #define Ri(x) scanf("%d",&x)
    #define Rii(x,y) scanf("%d%d",&x,&y)
    #define INF 0x3f3f3f3f
    using namespace std;
    template<class T>inline void read(T &res)
    {
        char c;T flag=1;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
        while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
    }
    typedef long long ll;
    const int maxn = 1e5 + 10;
    int a[maxn],ans[maxn],cnt[maxn],block;
    struct Node{
        int l,r,i;
        friend bool operator < (Node n1,Node n2){
            if(n1.l/block != n2.l/block) return n1.l < n2.l;
            return n1.r < n2.r;
        }
    }nd[maxn];
    int main(){
        IOS;
        int n,m,k,v;
        cin>>n>>m>>k;
        block = sqrt(n);
        rep(i,1,n){
            cin>>v;
            a[i] = a[i - 1] ^ v;
        }
        rep(i,1,m){
            cin>>nd[i].l>>nd[i].r;
            nd[i].i = i;nd[i].l --;
        }
        sort(nd + 1,nd + 1 + m);
        int l = 1,r = 0,num = 0;
        rep(i,1,m){
            while(r < nd[i].r){
                ++r;
                num += cnt[a[r] ^ k];
                ++cnt[a[r]];
            }
            while(r > nd[i].r){
                --cnt[a[r]];
                num -= cnt[a[r] ^ k];
                --r;
            }
            while(l < nd[i].l){
                --cnt[a[l]];
                num -= cnt[a[l] ^ k];
                ++l;
            }
            while(l > nd[i].l){
                --l;
                num += cnt[a[l] ^ k];
                ++cnt[a[l]];
            }
            ans[nd[i].i] = num;
        }
        rep(i,1,n){
            cout<<ans[i]<<endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    create-react-app 修改 webpack output.publicPath
    洛谷 P1282 多米诺骨牌 (01背包)
    UVa 1627
    UVa 1626
    UVa 11584
    UVa 11400
    UVa 116
    UVa 1347 Tour (dp)
    树形背包小结
    数据流图题目一
  • 原文地址:https://www.cnblogs.com/liuzuolin/p/14339083.html
Copyright © 2011-2022 走看看