题目链接:点击打开链接
大意:已知数组A[n]中A[1]=0,A[i]=(A[i-1]*m+z)%l,求对于数组B[m],B[1] xor B[2] …… B[m-1] xor B[m]的值。其中B[k]的值为(A[i]+A[j])。 思路: 假设A[4]={a,b,c,d};则B[k]=(A[i]+A[j])={a+a,a+b,a+c,a+d,b+a,b+b,b+c,b+d,c+a,c+b,c+c,c+d,d+a,d+b,d+c,d+d};则对于数组B[16],B[1] xor B[2] …… B[15] xor B[16] =(a+a)^(a+b)^(a+c)^(a+d)^(b+a)^(b+b)^(b+c)^(b+d)^(c+a)^(c+b)^(c+c)^(c+d)^(d+a)^(d+b)^(d+c)^(d+d) =(2a)^(a+b)^(a+c)^(a+d)^(b+a)^(2b)^(b+c)^(b+d)^(c+a)^(c+b)^(2c)^(c+d)^(d+a)^(d+b)^(d+c)^(2d) =(a+b)^(b+a)^(a+c)^(c+a)^(a+d)^(d+a)^(b+c)^(c+b)^(b+d)^(d+b)^(c+d)^(d+c)^(2a)^(2b)^(2c)^(2d) =0^0^0^0^0^0^(2a)^(2b)^(2c)^(2d) =(2a)^(2b)^(2c)^(2d) 如上例所示,对于B[1] ^ B[2] ^ …… ^ B[m-1] ^ B[m],可以任意交换两个数的位置,再进行异或运算,而对于B[k1]和B[k2],当B[k1]=A[i]+A[j],B[k2]=A[j]+A[i](i!=j)时,可以先运算B[k1] ^ B[k2] = 0,最终对于B[1] ^ B[2] ^ …… ^ B[m-1] ^ B[m],就是0^0^……^0^(A[1]+A[1])^(A[2]+A[2])^ …… ^(A[n-1]+A[n-1])^(A[n]+A[n])。
#include<cstdio> #include<algorithm> #include<cstring> #define LL long long using namespace std; LL n,m,z,l; int main() { int t; scanf("%d",&t); while(t--) { scanf("%lld%lld%lld%lld",&n,&m,&z,&l); LL a=0,ans=0; for(int i=2;i<=n;i++) { a=(a*m+z)%l; ans^=a; } printf("%lld\n",ans<<1); } return 0; }