BZOJ 2741 L (可持久化01Trie+分块)
题目大意:给你一个序列,共有$q$个询问,每次询问区间$[L,R]$内最大连续字段异或和,强制在线,$n<=12000,m<=5000$
有个细节没处理好$WA$了好久..还有一次$ans$没清零
先对序列建出可持久化$01Trie$
分块预处理出,任意两块所覆盖区域的最大$xor$和,枚举右侧块内的每个数,然后在$01Trie$里查找即可,预处理总时间$O(n \sqrt n)$
对于每次询问,中间部分的答案可以$O(1)$得到
边界情况,左侧不完整块内的每个数都要分别作为区间左端点和右端点在$01Trie$里查找最大值
右侧不完整块内的每个数作为区间右端点在01Trie里查找最大值即可,因为一旦出现它作为左端点的情况,它右面的数一定会作为右端点查询到它
时间$O(q\sqrt n+n\sqrt n)$
数据还挺强的
1 #include <cmath> 2 #include <queue> 3 #include <vector> 4 #include <cstdio> 5 #include <cstring> 6 #include <algorithm> 7 #define N1 12100 8 #define N2 420100 9 #define M1 120 10 #define ll long long 11 #define dd double 12 #define uint unsigned int 13 using namespace std; 14 15 int gint() 16 { 17 int ret=0,fh=1;char c=getchar(); 18 while(c<'0'||c>'9'){if(c=='-')fh=-1;c=getchar();} 19 while(c>='0'&&c<='9'){ret=ret*10+c-'0';c=getchar();} 20 return ret*fh; 21 } 22 23 int n,m,sq,tq; 24 uint bin[35]; 25 26 struct Trie{ 27 int ch[N2][2],num[N2],root[N1],tot; 28 void build() 29 { 30 root[0]=tot=1;int x=1; 31 for(int i=31;i>=0;i--){ 32 ch[x][0]=++tot; 33 x=ch[x][0],num[x]=1; 34 } 35 } 36 void insert(uint s,int rt1,int rt2,int w) 37 { 38 int x,y,p; 39 y=root[rt1]; 40 x=root[rt2]=++tot; 41 for(int i=31;i>=0;i--){ 42 p=(s&bin[i])?1:0; 43 ch[x][p]=++tot; 44 ch[x][p^1]=ch[y][p^1]; 45 num[ch[x][p]]=num[ch[y][p]]+w; 46 x=ch[x][p],y=ch[y][p]; 47 } 48 } 49 uint query(uint s,int l,int r) 50 { 51 int x,y,p;uint ans=0; 52 x=root[r]; 53 y=l<0?0:root[l]; 54 for(int i=31;i>=0;i--){ 55 p=(s&bin[i])?1:0; 56 if(num[ch[x][p^1]]-num[ch[y][p^1]]>0){ 57 x=ch[x][p^1],y=ch[y][p^1]; 58 ans|=bin[i]; 59 }else if(num[ch[x][p]]-num[ch[y][p]]>0){ 60 x=ch[x][p],y=ch[y][p]; 61 }else break; 62 }return ans; 63 } 64 }T; 65 66 uint a[N1],pa[N1]; 67 uint s1[M1][M1]; 68 int L[M1],R[M1]; 69 70 int main() 71 { 72 scanf("%d%d",&n,&m); 73 for(int i=0;i<=31;i++) 74 bin[i]=(1<<i); 75 int x,y; 76 T.build(); 77 for(int i=1;i<=n;i++) 78 { 79 a[i]=gint(); 80 pa[i]=pa[i-1]^a[i]; 81 T.insert(pa[i],i-1,i,1); 82 } 83 sq=sqrt(n);tq=n/sq; 84 for(int i=1;i<=tq+1;i++) 85 L[i]=(i-1)*sq+1,R[i]=min(n,i*sq); 86 for(int i=1;i<=tq;i++) 87 for(int j=i;j<=tq;j++) 88 { 89 s1[i][j]=s1[i][j-1]; 90 for(int k=L[j];k<=R[j];k++) 91 s1[i][j]=max(s1[i][j],T.query(pa[k],L[i]-2,k-1)); 92 } 93 uint ans=0;int px,py; 94 for(int j=1;j<=m;j++) 95 { 96 x=gint(),y=gint(); 97 x=(ans+x)%n+1,y=(ans+y)%n+1; 98 if(x>y) swap(x,y); 99 px=(x-1)/sq+1,py=(y-1)/sq+1; 100 if(px!=py){ 101 ans=s1[px+1][py-1]; 102 for(int i=x;i<=R[px];i++) 103 ans=max(ans,T.query(pa[i],x-2,i-1)); 104 for(int i=x-1;i<=R[px]-1;i++) 105 ans=max(ans,T.query(pa[i],i,y)); 106 for(int i=L[py];i<=y;i++) 107 ans=max(ans,T.query(pa[i],x-2,i-1)); 108 }else{ 109 ans=0; 110 for(int i=x;i<=y;i++) 111 ans=max(ans,T.query(pa[i],x-2,i-1)); 112 } 113 printf("%u\n",ans); 114 } 115 return 0; 116 }