zoukankan      html  css  js  c++  java
  • 【BZOJ4347】[POI2016]Nim z utrudnieniem DP

    【BZOJ4347】[POI2016]Nim z utrudnieniem

    Description

    A和B两个人玩游戏,一共有m颗石子,A把它们分成了n堆,每堆石子数分别为a[1],a[2],...,a[n],每轮可以选择一堆石子,取掉任意颗石子,但不能不取。谁先不能操作,谁就输了。在游戏开始前,B可以扔掉若干堆石子,但是必须保证扔掉的堆数是d的倍数,且不能扔掉所有石子。A先手,请问B有多少种扔的方式,使得B能够获胜。

    Input

    第一行包含两个正整数n,d(1<=n<=500000,1<=d<=10)。
    第二行包含n个正整数a[1],a[2],...,a[n](1<=a[i]<=1000000)。
    本题中m不直接给出,但是保证m<=10000000。

    Output

    输出一行一个整数,即方案数对10^9+7取模的结果。

    Sample Input

    5 2
    1 3 4 1 2

    Sample Output

    2

    题解:一开始没看到m是所有石子个数的和,GG。。。

    Nim游戏结论(说n遍了):所有堆的石子数异或和不为0则先手必胜,否则先手必败。

    这个有什么用?我们将所有堆从小到大排序,对于一个数x,它和比它小的数中任意一些数的异或和不会超过2*x,所以直接DP,用f[i][j]表示当前异或和为i,选出石子的堆数%d=j的方案数,答案就是f[0][n%d](也可以是f[sum][0])

    但是TLE啊,狂T不止啊,要了数据手动测了30个点都没问题啊,不就是std新开了一个数组temp,而我吧temp和f数组合到一起了吗~

    还好有网上的黑科技,将f[i][j]换成f[j][i]就过了,从TLE变成14s。

    顿时觉得二位数组的复杂度真的玄学,估计那天丧心病狂开它12个一维数组没准就rank1了?实在不行写循环展开?(orz wys!orz wys!orz wys! O(wys)!O(wys)!O(wys)!)

    #include <cstdio>
    #include <algorithm>
    #define mod 1000000007
    using namespace std;
    int n,m,d,ans;
    int v[500010],f[12][1<<20];
    int rd()
    {
    	int ret=0;	char gc=getchar();
    	while(gc<'0'||gc>'9')	gc=getchar();
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret;
    }
    int main()
    {
    	n=rd(),d=rd();
    	int i,j,k,x;
    	for(i=1;i<=n;i++)	v[i]=rd();
    	sort(v+1,v+n+1),f[0][0]=1;
    	for(i=m=1;i<=n;i++)
    	{
    		x=v[i];
    		while(m<=x)	m<<=1;
    		for(k=0;k<m;k++)	f[d][k]=f[d-1][k];
    		for(j=d-1;j;j--)	for(k=0;k<m;k++)
    		{
    			f[j][k]+=f[j-1][k^x];
    			if(f[j][k]>=mod)	f[j][k]-=mod;
    		}
    		for(k=0;k<m;k++)
    		{
    			f[0][k]+=f[d][k^x];
    			if(f[0][k]>=mod)	f[0][k]-=mod;
    		}
    	}
    	ans=f[n%d][0];
    	if(n%d==0)	ans--;
    	if(ans<0)	ans+=mod;
    	printf("%d",ans);
    	return 0;
    }
  • 相关阅读:
    自定义分页二
    CheckBox实现跨页面多选
    正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。
    DropDownList下拉框多选
    通用查询
    AutoCAD自动加载DLL文件的方法
    软件开发(团队管理)
    正确地做事与做正确的事
    C#.NET实现邮件的发送
    多附件的上传
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7054703.html
Copyright © 2011-2022 走看看