首先看一下题吧:题意就是让你把一个序列里所有的(Ai+Aj) 的异或求出来。(1<=i,j<=n)
2 3 5 5 7 6 8 8 9
14 16
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<queue> #include<stack> #include<map> #include<iostream> #include<set> using namespace std; #define LL long long #define _LL __int64 #define max1(a,b) (a)>(b)?(a):(b) #define min1(a,b) (a)<(b)?(a):(b) #define pi acos(-1.0) #define eps 1e-8 #define me(a,b) memset(a,b,sizeof(a)) long long a[500009]; int main() { int t; scanf("%d",&t); int n,m,z,l; while(t--) { scanf("%d%d%d%d",&n,&m,&z,&l); a[1]=0; long long sum=0; for(int i=2;i<=n;i++) { a[i]=(a[i-1]*m+z)%l; sum=sum^a[i]; } // for(int i=2;i<=n;i++) // for(int j=2;j<=n;j++) // { // sum=sum^(a[i]+a[j]); // } printf("%I64d\n",sum*2); } return 0; }
1 ^ 1=0
1 ^ 0=1
0 ^ 1=1
0 ^ 0=0
即二进制相同位 相同时值为0,不同时值为 1
在暴力 n^2的循环中 (Ai +Aj)^(Aj+Ai)==0 ,0异或任何正数都是那个正数。 所以可以舍弃它们。于是只剩下了 (Ai+Ai)^(Aj+Aj)(i!=j);即(2*Ai)^(2*Aj)==2*(Ai^Aj)。误打误撞之下对了。
异或的用途:
1):可判断两数是否相等
2): 可进行两个数的交换 swap(i,j): i=i^j; j=j^i; i=i^j; 可以这样串起来想 J=J^J^I; I=I^I^j;
3):可以实现一个数的二进制某几位的翻转,如想翻转第二,三,五位 , 直接异或 0000 0000 0001 0110 即可。
版权声明:本文为博主原创文章,未经博主允许不得转载。
hdu 5344 (多校联赛) MZL's xor --- 位运算
原文地址:http://blog.csdn.net/stffer/article/details/47310759