2021-08-24 SSL 模拟赛 T1
怎么又开始没有标题了?
这是一道散兵题,我也是散兵。
题目大意:
给你一个序列,问你怎么划分才能使得数列中每一段的异或之和最大。
思路:
众所周知,对与每一个二进制数,二进制的每一位上做异或运算,有:
0
x
o
r
1
=
1
,
0
x
o
r
0
=
0
,
1
x
o
r
1
=
0
0~xor~1=1,0~xor~0=0,1~xor~1=0
0 xor 1=1,0 xor 0=0,1 xor 1=0
有没有发现异或运算其实就是加法不进位。
所以很明显有一个这样的式子:
a
x
o
r
b
≤
a
+
b
a~xor~b\leq a+b
a xor b≤a+b
那么这样子我们就不需要划分数列了,因为划分后我们要取它们的和,那我还不如继续异或下去呢。
所以答案就是每个数的异或起来的值。
果然是一道散兵题,不过比赛时我这个散兵也没写出来
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#define r register
//#define ull unsigned long long
#define rep(i,x,y) for(r ll i=x;i<=y;++i)
#define per(i,x,y) for(r ll i=x;i>=y;--i)
using namespace std;
typedef long long ll;
ll n,a[1000000];
inline ll in()
{
ll res=0,f=1;
char ch;
while((ch=getchar())<'0'||ch>'9')
if(ch=='-') f=-1;
res=res*10+ch-48;
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-48;
return res*f;
}
inline void put(ll x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) put(x/10);
putchar(x%10+48);
}
int main()
{
ll sum=0;
n=in();
rep(i,1,n)
a[i]=in(),sum^=a[i];
cout<<sum;
return 0;
}