题目链接:https://nanti.jisuanke.com/t/38230
题目大意
给定一个序列,层层定义三个函数,
定义都是数学式子很复杂,但是终归就是
每一位的数取还是不取的关系.
题目分析
第一层:1,1,1,1,1
第二层:1,0,1,0,1,事实上就是上一层前缀和模2,
第三层:1,1,0,0,1,1,0,0,...
到这里即可,
那么分析,对于(l,r)这样的查询区间,
每个数其确定是否贡献的函数,比如如果区间长度是4吧:
1 4
2 3
3 2
4 1
可以知道这四对数没有一对产生贡献,
可以推广到4n长度,与此同时那么4n+1,4n+2,4n+3也可以推断,
分别把右边序列向下偏移一位,
贡献状态分别是:
每四个取第一个数,每四个取第一二个数,每四个取第二个数.
刚开始我还在想着从前往后,但这个序列贡献有点小小的对称思想,
应该从后往前看,我们定义dp[i]为从i往1开始,每四个一组第一个产生贡献的
异或前缀和,明显这个dp[i]是可以线性搞定的,
那么就分类寻找递推关系:
4n长度肯定是0,
4n+1长度是dp[r]^dp[l-4](注意利用首尾一致这样的特点),
4n+2长度是dp[r]^dp[l-3]^dp[r-1]^dp[l-4],
4n+3长度是dp[r-1]^dp[l-3].
#include<bits/stdc++.h>
using namespace std;
#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define ll long long
#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root l,r,rt
#define mst(a,b) memset((a),(b),sizeof(a))
#define pii pair<int,int>
#define fi first
#define se second
#define mk(x,y) make_pair(x,y)
const int mod=1e9+7;
const int maxn=1e5+100;
const int ub=1e6;
ll powmod(ll x,ll y){ll t; for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod; return t;}
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
/*
题目大意:
给定一个序列,层层定义三个函数,
定义都是数学式子很复杂,但是终归就是
每一位的数取还是不取的关系.
题目分析:
第一层:1,1,1,1,1
第二层:1,0,1,0,1,事实上就是上一层前缀和模2,
第三层:1,1,0,0,1,1,0,0,...
到这里即可,
那么分析,对于(l,r)这样的查询区间,
每个数其确定是否贡献的函数,比如如果区间长度是4吧:
1 4
2 3
3 2
4 1
可以知道这四对数没有一对产生贡献,
可以推广到4n长度,与此同时那么4n+1,4n+2,4n+3也可以推断,
分别把右边序列向下偏移一位,
贡献状态分别是:
每四个取第一个数,每四个取第一二个数,每四个取第二个数.
刚开始我还在想着从前往后,但这个序列贡献有点小小的对称思想,
应该从后往前看,我们定义dp[i]为从i往1开始,每四个一组第一个产生贡献的
异或前缀和,明显这个dp[i]是可以线性搞定的,
那么就分类寻找递推关系:
4n长度肯定是0,
4n+1长度是dp[r]^dp[l-4](注意利用首尾一致这样的特点),
4n+2长度是dp[r]^dp[l-3]^dp[r-1]^dp[l-4],
4n+3长度是dp[r-1]^dp[l-3].
*/
int n,a[maxn];
int solve(int l,int r){
int ans=0,flag=(r-l+1)%4;
if(flag==0) return 0;
else if(flag==1){
ans=a[r];
if(l>=4) ans^=a[l-4];
}else if(flag==2){
ans=a[r]^a[r-1];
if(l>=3) ans^=a[l-3];
if(l>=4) ans^=a[l-4];
}else{
ans=a[r-1];
if(l>=3) ans^=a[l-3];
}
return ans;
}
int main(){
int t;scanf("%d",&t);
while(t--){
scanf("%d",&n);
rep(i,1,n+1) scanf("%d",&a[i]);
rep(i,4,n+1) a[i]^=a[i-4];
int q;scanf("%d",&q);
while(q--){
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",solve(x,y));
}
}
return 0;
}