@xzyxzy
2018-08-05T21:55:54.000000Z
字数 956
阅读 1395
题解
不同于树的删边游戏,删掉一个点删去的是到根的路径
这题只和计算有关,博弈的有关内容可以移步这篇博客
这和翻棋子游戏不同!每个点不能单独考虑
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
int read()
{
char ch=getchar();int h=0,t=1;
while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
if(ch=='-') t=-1,ch=getchar();
while(ch>='0'&&ch<='9') h=h*10+ch-'0',ch=getchar();
return h*t;
}
const int mod=998244353;
const int N=1<<21;
const int inv=499122177;
int n,A[N],B[N],bit3[N],l;
void FWT_xor(int *P,int op)
{
for(int i=1;i<l;i<<=1)
for(int j=0,p=i<<1;j<l;j+=p)
for(int k=0;k<i;k++)
{
int X=P[j+k],Y=P[j+k+i];
P[j+k]=1ll*(X+Y)%mod*op%mod;
P[j+k+i]=1ll*((X-Y)%mod+mod)*op%mod;
}
}
int main()
{
n=read();A[0]=n;bit3[0]=1;int mx=0;
for(int i=1;i<=n;i++) bit3[i]=bit3[i-1]*3ll%mod;
for(int i=1,x;i<=n;i++) A[x=read()]+=2,mx=max(mx,x);
for(l=1;l<=mx;l<<=1);
FWT_xor(A,1);
for(int i=0;i<l;i++)
{
int x=(3ll*n-A[i]+mod)*inv%mod*inv%mod;
A[i]=bit3[n-x]; if(x&1) A[i]=mod-A[i];
}
FWT_xor(A,inv);
printf("%d\n",(A[0]-1+mod)%mod);
}