传送门
•题意
一个数组a有n个数 m个操作
操作① 询问$[l,r]$区间的异或值
操作② 在数组末尾追加一个数x,数组长度变为$n+1$
其中$l,r$不直接给出,其中$l=l%n+1,r=r%n+1$
其中$x=x^lastans$($lastens$为上一次询问的答案)
•思路
强制在线的线性基,
在线线性基就是在离线的基础上多开一维
具体思路跟CF1100F的在线做法一样,戳这里
记得处理一下$l,r,x$
•代码
View Code1 #include2 using namespace std; 3 const int maxn=5e6+5; 4 int a[maxn]; 5 int p[maxn][40],base[maxn][40]; 6 int n,q; 7 int last; 8 9 void Insert(int k,int x,int pos) 10 { 11 for(int i=30;i>=0;i--) 12 { 13 if(x&(1<<i)) 14 { 15 if(!base[k][i]) 16 { 17 base[k][i]=x; 18 p[k][i]=pos; 19 return ; 20 } 21 else if(pos>p[k][i]) 22 { 23 swap(base[k][i],x); 24 swap(p[k][i],pos); 25 } 26 x^=base[k][i]; 27 } 28 } 29 } 30 31 int getMax(int l,int r) 32 { 33 int ans=0; 34 for(int i=30;i>=0;i--) 35 if(p[r][i]>=l) 36 ans=max(ans,ans^base[r][i]); 37 38 return ans; 39 } 40 41 void Solve() 42 { 43 for(int i=1;i<=n;i++) 44 { 45 memcpy(p[i],p[i-1],sizeof(p[i-1])); 46 memcpy(base[i],base[i-1],sizeof(base[i-1])); 47 48 Insert(i,a[i],i); 49 } 50 51 while(q--) 52 { 53 int op; 54 scanf("%d",&op); 55 if(op==0) 56 { 57 int l,r; 58 scanf("%d%d",&l,&r); 59 l=(l^last)%n+1,r=(r^last)%n+1; 60 if(l>r) 61 swap(l,r); 62 last=getMax(l,r); 63 printf("%d\n",last); 64 } 65 else 66 { 67 n++; 68 scanf("%d",&a[n]); 69 memcpy(p[n],p[n-1],sizeof(p[n-1])); 70 memcpy(base[n],base[n-1],sizeof(base[n-1])); 71 72 Insert(n,a[n]^last,n); 73 } 74 } 75 } 76 77 int main() 78 { 79 int t; 80 scanf("%d",&t); 81 while(t--) 82 { 83 last=0; 84 scanf("%d%d",&n,&q); 85 for(int i=1;i<=n;i++) 86 scanf("%d",a+i); 87 88 Solve(); 89 } 90 }