P5970 [POI2016]Nim z utrudnieniem
CI_is_safe · · 题解
P5970 [POI2016]Nim z utrudnieniem 题解
题目传送门
思路
Nim 游戏各堆异或和是否为零即可判断答案,不必多说,关键在于扔掉石子的操作。设原来石子的异或和为
代码
#include<bits/stdc++.h>
using namespace std;
#define L(i,l,r) for(int i=l;i<=r;++i)
#define R(i,l,r) for(int i=r;i>=l;--i)
const int N=500010,D=11,mod=1e9+7;
int n,d,f[D][4*N],a[N],g[4*N],s;
int main(){
scanf("%d%d",&n,&d);
L(i, 1, n)scanf("%d",a+i),s^=a[i];
sort(a+1,a+1+n);
f[0][0]=1;
int u=1;
L(i, 1, n){
while(u<=a[i])u<<=1;
L(j, 0, u-1)g[j]=(f[d-1][j^a[i]]+f[0][j])%mod;
R(j, 1, d-1)
L(k, 0, u-1)f[j][k]=(f[j][k]+f[j-1][k^a[i]])%mod;
L(j,0,u-1)f[0][j]=g[j];
}
if(n%d==0)f[0][s]--;
if(f[0][s]<0)f[0][s]+=mod;
printf("%d",f[0][s]);
return 0;
}