zoukankan      html  css  js  c++  java
  • BZOJ 5301: [Cqoi2018]异或序列 莫队+桶

    开一个桶记录一下前缀异或值的个数即可.   

    注意要把询问从 $(l,r)$ 变成 $(l-1,r)$,这样做的话会方便很多. 

    code: 

    #include <cstdio> 
    #include <cmath>  
    #include <algorithm> 
    #define N 1000005    
    #define ll long long 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;       
    ll ans=0ll;  
    int n,m,k,B,K;     
    int a[N],h[N],cnt[N];       
    ll answer[N];    
    struct node 
    {
        int l,r,id;     
        node(int l=0,int r=0,int id=0):l(l),r(r),id(id){}  
    }q[N];   
    bool cmp(node x,node y)  
    {
        return x.l/B==y.l/B?x.r<y.r:x.l<y.l;    
    }    
    void del(int x) 
    {        
        ans-=cnt[K^x];  
        --cnt[x];      
    }
    void add(int x) 
    {    
        ++cnt[x];     
        ans+=cnt[K^x];        
    } 
    int main() 
    { 
        // setIO("input");    
        int i,j,l=2,r=1;   
        scanf("%d%d%d",&n,&m,&K),B=sqrt(n); 
        for(i=1;i<=n;++i) scanf("%d",&a[i]),h[i]=h[i-1]^a[i];         
        for(i=1;i<=m;++i) scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i,--q[i].l;    
        sort(q+1,q+1+m,cmp);     
        for(i=1;i<=m;++i) 
        {
            while(l>q[i].l) add(h[--l]);              
            while(r<q[i].r) add(h[++r]);    
            while(l<q[i].l) del(h[l++]);    
            while(r>q[i].r) del(h[r--]);     
            answer[q[i].id]=ans;  
        }   
        for(i=1;i<=m;++i) printf("%lld
    ",answer[i]);   
        return 0;
    }
    

      

  • 相关阅读:
    举重若轻是一种大气的生活态度
    论自我发展与自我职场生存
    ASP.Net与IIS原理粗浅的理解
    Net反射效率(转载)
    MVC技术
    单件模式 多线程
    公司的机票返利项目总结
    JS调用google地图
    System.Runtime.Serialization报错查找
    信息采集
  • 原文地址:https://www.cnblogs.com/guangheli/p/12248831.html
Copyright © 2011-2022 走看看