zoukankan      html  css  js  c++  java
  • P5312 [Ynoi2011]D2T1

    思路:01trie 按位维护

    提交:5边

    错因:爆int + 少处理询问时的右端点

    题解:

    见代码(已经不想说什么了)

    代码

    //I have my own flg; 
    #include<bits/stdc++.h>
    #define ll long long
    #define R register int
    using namespace std;
    namespace Luitaryi {
    inline int g() { R x=0,f=1;
      register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
      do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*f;
    } const int L=29,N=200010;
    int n,cnt,m,tot,a[N],s[N][30],ch[N*15][2],dat[N*15][30],sz[N*15];
    int cur,lst;
    inline void ins(int x) { R tr=0;
      for(R i=L;~i;--i) { R c=x>>i&1;
        if(!ch[tr][c]) ch[tr][c]=++tot;
        tr=ch[tr][c],++sz[tr];
        for(R j=0;j<=L;++j) dat[tr][j]+=x>>j&1;//按位存储子树中每一位出现的次数
      }
    }
    inline ll query(int k) {
      R tr=0,vl=0; register ll ret=0;
      for(R i=L;~i;--i) { R c=lst>>i&1;
        if(sz[ch[tr][c]]>=k) tr=ch[tr][c];
        else {
          R t=ch[tr][c]; k-=sz[t],vl|=1<<i;//右子树,即1,记录遍历到所有1的值。
          for(R j=0,d;j<=L;++j) {//按位处理左子树每一位的贡献
            d=dat[t][j];
            if(cur>>j&1) d=sz[t]-d;//注意如果现在有标记要取反
            ret+=1ll*d<<j;
          } tr=ch[tr][c^1];
        }
      } vl^=lst^cur;//vl相当于是在trie树中已经经过lst标记的数,所以要抵消掉cur中的lst
      return ret+1ll*vl*k;//k是最后剩下的应该的右子树的个数
    }
    inline void push() {for(R i=0;i<=L;++i) s[cnt][i]=s[cnt-1][i]+(a[cnt]>>i&1);}
    inline void calc(int l,int r) { register ll ret=0;
      if(l<=n) ret+=query(min(r,n))-query(l-1);
      if(r>n) {l=max(l,n+1); R sum=r-l+1; 
        for(R i=0;i<=L;++i) {
          if(cur>>i&1) ret+=1ll*(sum-s[r][i]+s[l-1][i])<<i;
          else ret+=1ll*(s[r][i]-s[l-1][i])<<i;
        }
      } printf("%lld
    ",ret);
    }
    inline void main() {
      //lst表示trie树中xor后的0。
      //lst会告诉你走trie树的左边还是右边
      //cur是所有标记的累加。
      //trie树中存的数都是在最开始的时间点上的。
      cnt=g(); for(R i=1;i<=cnt;++i) { a[i]=g(); 
        for(R j=0;j<=L;++j) s[i][j]=s[i-1][j]+(a[i]>>j&1);//后面未排序的直接维护按位的前缀和
      } m=g(); for(R i=1,op,l,r;i<=m;++i) { op=g();
        if(op==1) a[++cnt]=g()^cur,push();
        if(op==2) l=g(),r=g(),calc(l,r);
        if(op==3) cur^=g();
        if(op==4) {for(R i=n+1;i<=cnt;++i) ins(a[i]); n=cnt,lst=cur;}
      }
    }
    } signed main() {Luitaryi::main(); return 0;}
    

    2019.09.17
    59
    flg总算没有倒

  • 相关阅读:
    vagrant+virtualbox 构建mac虚拟机环境
    python dns模块
    Ansible模块开发-自定义模块
    nginx rewrite 踩坑
    死磕nginx系列--nginx 目录
    死磕salt系列-salt文章目录汇总
    ant jmeter jenkins 实现自动化测试
    prometheus-入门尝试
    redis-Sentinel配置
    devops工具-Ansible进阶playbook&roles
  • 原文地址:https://www.cnblogs.com/Jackpei/p/11537276.html
Copyright © 2011-2022 走看看