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总算没有倒

原文地址:https://www.cnblogs.com/Jackpei/p/11537276.html