# BZOJ 2741 L (可持久化01Trie+分块)

  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 }

posted @ 2018-11-28 15:38  guapisolo  阅读(156)  评论(0编辑  收藏  举报