CF662A Gambling Nim 线性基
挺好的一道题.
判断先手必胜即判断所有数异或值是否为 0.
直接判断的话不好做,不妨先强制所有数选 a,然后再看有几种方案使得选一些 b 让序列异或值为 0.
假如想让位置 i 从 a->b,要异或上 $a_{i}$ xor $b_{i}$.
那么,就先求出所有 $a_{i}$ 的异或和 sum,然后将 $a_{i}$ xor $b_{i}$ 扔到线性基里,看看有几种方案使得线性基里异或和等于 sum.
根据线性基的相关定理,每种异或和出现次数都是相同,所有输出 $2^{size}-1/2^{size}$ 即可.
code:
#include <cstdio>
#include <algorithm>
#define N 64
#define ll long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
ll p[63];
int cnt=0;
int ins(ll x) {
for(int i=62;i>=0;--i) {
if(x&(1ll<<i)) {
if(p[i])
x^=p[i];
else {
p[i]=x;
++cnt;
return 1;
}
}
}
return 0;
}
int main() {
// setIO("input");
int n;
scanf("%d",&n);
ll sum=0;
for(int i=1;i<=n;++i) {
ll a,b;
scanf("%lld%lld",&a,&b);
sum^=a;
ins(a^b);
}
if(ins(sum)) printf("1/1\n");
else {
printf("%lld/%lld\n",(1ll<<cnt)-1,1ll<<cnt);
}
return 0;
}

浙公网安备 33010602011771号