题意
给出一个序列,相邻两两异或,生成一个新序列,再相邻两两异或,直到只剩下一个元素,问最后结果为多少。m个查询,每次都有一个待查询区间。
分析
既然有多组查询,n只是1e4,那么可以考虑预处理。
预处理出每种长度的区间最后剩下的元素位置。然后就O(1)查询了。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <vector> using namespace std; const int maxn=1e4+10; const int inf=0x3f3f3f3f; const int mod=1e9+7; int a[maxn],num[maxn]; vector<int> v[maxn]; void init(){ for(int i=1;i<maxn;i++){ num[1]=num[i]=1; for(int j=i-1;j>1;j--) num[j]^=num[j-1]; for(int j=1;j<=i;j++) if(num[j]) v[i].push_back(j); } } int main(){ init(); int t; scanf("%d",&t); for(int k=1;k<=t;k++){ int n; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); int q; scanf("%d",&q); printf("Case %d: ",k); while(q--){ int l,r; scanf("%d%d",&l,&r); int ans=0; for(int i=0;i<v[r-l+1].size();i++) ans^=a[l+v[r-l+1][i]-1]; printf("%d ",ans); } } return 0; }