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

    思路

    把序列求前缀异或和一下
    问题转变成了[l,r]中有多少个数对(x,y)的异或和为k
    然后莫队就好了

    代码

        #include <cstdio>
        #include <algorithm>
        #include <cstring>
        #include <cmath>
        using namespace std;
        int n,m,k,a[100100],belong[100100],sz,num,L,R,ans[100100],barrel[2001000],sum=0;
        struct Query{
            int l,r,id;
            bool operator < (const Query &b){
                return (belong[l]==belong[b.l])?r<b.r:belong[l]<belong[b.l];
            }
        }Q[100100];
        void init(void){
            sz=sqrt(n);
            num=n/sz;
            if(n%sz)
                num++;
            for(int i=1;i<=n;i++)
                belong[i]=i/sz+1;
        }
        void moveL(int opt){
            if(opt==1){
                barrel[a[L]]--;
                sum-=barrel[k^a[L]];
                L++;
            }
            else{
                L--;
                sum+=barrel[k^a[L]];
                barrel[a[L]]++;
            }
        }
        void moveR(int opt){
            if(opt==1){
                R++;
                sum+=barrel[k^a[R]];
                barrel[a[R]]++;
            }
            else{
                barrel[a[R]]--;
                sum-=barrel[k^a[R]];
                R--;
            }
        }
        int main(){
            scanf("%d %d %d",&n,&m,&k);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]),a[i]^=a[i-1];
            init();
            for(int i=1;i<=m;i++){
                scanf("%d %d",&Q[i].l,&Q[i].r);
                Q[i].l--;
                Q[i].id=i;
            }
            sort(Q+1,Q+m+1);
            L=1;
            R=0;
            sum=0;
            for(int i=1;i<=m;i++){
                while(L<Q[i].l)
                    moveL(1);
                while(L>Q[i].l)
                    moveL(-1);
                while(R<Q[i].r)
                    moveR(1);
                while(R>Q[i].r)
                    moveR(-1);
                ans[Q[i].id]=sum;
            }
            for(int i=1;i<=m;i++)
                printf("%d
    ",ans[i]);
            return 0;
        }
    
  • 相关阅读:
    Redpine的Lite-Fi解决方案获Wi-Fi CERTIFIED认证
    植物园偶遇一直喵
    美食篇
    端午节路过南站
    黄山云海
    一品黄山 天高云淡
    黄山的日出日落
    宏村,寻找你的前世今生
    git把本地文件上传到github上的步骤
    一张照片一个故事
  • 原文地址:https://www.cnblogs.com/dreagonm/p/10804858.html
Copyright © 2011-2022 走看看