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; }