JZOJ6020.【GDOI2019】模拟 石子游戏(Nim)

Description

JZOJ6020.【GDOI2019】模拟 石子游戏(Nim)_第1张图片

1<=n,A=max(a[i])<=5e5,

Solution

  • Nim游戏的基本结论,当石子数异或和为0时先手必败,否则必胜。
  • 即要求最多的数异或和为0.
  • 反过来求最少的数异或和为所有的数的异或和。
  • 假定我们将所有的数丢入线性基,那么至少log个数就可以构成所有的情况,所以答案上界为20.
  • 接下来我们直接用fwt,每一次与自己相乘(多项式的乘法)。虽然可能会自己乘上自己,但是这对答案并没有影响,因为这个答案一定不如消去这两次的答案更优。
  • 具体来说设f[i]表示能否异或乘i(在自乘了若干次后)。最后查询的是f[s]是否为0。
  • 时间复杂度是Alog2A的。
  • 但是s是固定的,可以预先推算出其他位置对这个s位置的贡献的系数。
  • 有一个结论,位置t贡献系数为(-1)|s&t中1的个数|
  • 然后就可以预处理点值表达,每次O(n)自乘,O(n)求IFWT。
  • 注意取模(随便模一个质数)。
#include
#include
#include 
#include
#define maxn 500005
#define ll long long 
#define mo 998244353
using namespace std;

int n,i,j,k,a[maxn],s,lim,A,nm;
ll f[maxn*2],g[maxn*2],ct[maxn*2],sum;

void fwt(ll *a,int sig){
	for(int mid=1;mid0) {printf("%d\n",n-i);break;}
	}
}

你可能感兴趣的:(题解,nim游戏,fwt,多项式)