分块预处理,表示f[][],第i块到第j个数的答案
这样做的时候就可以大块直接查询,小块暴力查询
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define getsz(p) (p?p->sz:0) using namespace std; typedef long long ll; typedef pair<ll,int> pll; const int N=1e5+10; struct node{ ll sz; node * nxt[2]; }*rt[N],pool[N*30]; ll f[400][16000]; ll s[N],idx,n,block,B; node *copynode(node *rt){ node *p=pool+(++idx); pool[idx]=*rt; return p; } node* insert(node* rt, int x, int dep){ node *p; if(rt) p = copynode(rt); else{ p=pool+(++idx); p->sz=0; } ++p->sz; if(dep < 0) return p; int y = (x>>dep)&1; if(!y) p->nxt[0] = insert(p->nxt[0], x, dep-1); else p->nxt[1] = insert(p->nxt[1], x, dep-1); return p; } ll query(node* pL, node* pR, int x, int dep){ int diff, y; ll ans = 0; for(int dep=30;dep>=0;dep--){ y = (x>>dep)&1; if(!pL){ diff = getsz(pR->nxt[!y]); if(diff){ ans += (1<<dep); pR = pR->nxt[!y]; } else pR = pR->nxt[y]; } else{ diff = getsz(pR->nxt[!y]) - getsz(pL->nxt[!y]); if(diff){ ans += (1<<dep); pL = pL->nxt[!y]; pR = pR->nxt[!y]; } else{ pL = pL->nxt[y]; pR = pR->nxt[y]; } } } return ans; } ll dp[500][14000]; void init(){ B = sqrt(n); for(int i=0;i<=n;i+=B){ for(int j=i+1;j<=n;j++){ if(i==0) dp[i/B][j] = max(dp[i/B][j-1], query(0, rt[j], s[j], 30)); else dp[i/B][j] = max(dp[i/B][j-1], query(rt[i-1], rt[j], s[j],30)); } } } int main(){ ios::sync_with_stdio(false); int m; cin>>n>>m; int i; rt[0]=insert(rt[0],0,30); for(i=1;i<=n;i++){ int x; cin>>x; s[i]=s[i-1]^x; rt[i]=insert(rt[i-1],s[i],30); } init(); ll last=0; while(m--){ ll l,r; cin>>l>>r; l = (l+last)%n + 1; r = (r+last)%n + 1; if(l>r) swap(l,r); l--; int x=(l/B+1)*B; if(x<=r){ last=dp[l/B+1][r]; } else last=0; for(i=l;i<x&&i<=r;i++){ last=max(last,query(rt[i],rt[r],s[i],30)); } cout<<last<<endl; } return 0; }