zoukankan      html  css  js  c++  java
  • JZOJ6020.【GDOI2019】模拟 石子游戏(Nim)

    Description

    在这里插入图片描述

    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<cstdio>
    #include<cmath>
    #include<algorithm> 
    #include<cstring>
    #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;mid<lim;mid<<=1)
    		for(int j=0;j<lim;j+=mid<<1)
    			for(int k=0;k<mid;k++) {
    				ll x=a[j+k],y=a[j+k+mid];
    				a[j+k]=(x+y)%mo;
    				a[j+k+mid]=(x-y+mo)%mo;
    			}
    }
    
    int main(){
    	freopen("nim.in","r",stdin);
    	freopen("nim.out","w",stdout);
    	scanf("%d",&n);
    	for(i=1;i<=n;i++) scanf("%d",&a[i]),s^=a[i],A=max(A,a[i]);
    	A=max(A,s);
    	for(lim=1,nm=0;lim<=A;lim<<=1,nm++);
    	for(i=1;i<lim;i++) ct[i]=ct[i-(i&-i)]+1;
    	
    	if (s==0){printf("%d
    ",n);return 0;}
    	
    	for(i=1;i<=n;i++) g[a[i]]++;
    	fwt(g,1);
     	memcpy(f,g,sizeof(f));
    	for(i=1;i<=(int)log2(A);i++){
    		sum=0;
    		for(j=0;j<lim;j++) {
    			sum=(sum+((ct[j&s]&1)?-1:1)*f[j]%mo+mo)%mo;
    			f[j]=f[j]*g[j]%mo;
    		}
    		if (sum>0) {printf("%d
    ",n-i);break;}
    	}
    }
    
  • 相关阅读:
    Linux文件默认权限和umask笔记
    Linux文件默认权限和umask笔记
    Linux关于文件的权限笔记
    Linux关于文件的权限笔记
    Linux文件和目录权限笔记
    Linux文件和目录权限笔记
    Linux文件目录基础笔记
    Linux文件目录基础笔记
    spark在collect收集数据的时候出现outOfMemoryError:java heap space
    查看hadoop压缩方式
  • 原文地址:https://www.cnblogs.com/DeepThinking/p/11700953.html
Copyright © 2011-2022 走看看