首先看一下题吧:题意就是让你把一个序列里所有的(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