联考20200520 T3 画(小P的画)



分析:
吴思扬神仙题解Orz

不说了,3进制状压太恐怖,写(chao)半天
(这种题考场上就写暴力吧)

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<iostream>
#include<map>
#include<string>

#define maxn 16
#define INF 0x3f3f3f3f
#define MOD 998244353

using namespace std;

inline long long getint()
{
	long long num=0,flag=1;char c;
	while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
	while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
	return num*flag;
}

int n,m,N,ans;
long long C,a[maxn];
int pos[maxn],id[maxn];
int fe[1<<maxn],coef[1<<maxn];
int sz[1<<maxn],lg[1<<maxn];
int st[1<<maxn];
int fn[1<<maxn],pw3[maxn],f[44000005];
long long ar[maxn],cnt;
long long pw2[61];
inline bool cmp(int x,int y){return a[x]<a[y];}	
inline int add(int x,int y){return x+y<MOD?x+y:x+y-MOD;}

inline int solve(int s)
{
	cnt=0;
	long long Num=C;int ret=0;
	for(int i=0;i<n;i++)if((s>>i)&1)ar[++cnt]=a[i];
	while(1)
	{
		if(Num>ar[cnt]&&(Num^ar[cnt])>ar[cnt])return ret;
		if(!ar[cnt])return ret+1;
		long long t=1ll<<(upper_bound(pw2,pw2+60,ar[cnt])-pw2-1);
		int dp[2][2]={},now=1,pre=0;
		dp[pre][0]=1;
		for(int i=1;i<cnt;i++,swap(now,pre))
		{
			if(ar[i]>=t)
			{
				dp[now][0]=add(1ll*dp[pre][0]*(t%MOD)%MOD,1ll*dp[pre][1]*((ar[i]-t+1)%MOD)%MOD);
				dp[now][1]=add(1ll*dp[pre][1]*(t%MOD)%MOD,1ll*dp[pre][0]*((ar[i]-t+1)%MOD)%MOD);
			}
			else
			{
				dp[now][0]=1ll*dp[pre][0]*((ar[i]+1)%MOD)%MOD;
				dp[now][1]=1ll*dp[pre][1]*((ar[i]+1)%MOD)%MOD;
			}
		}
		ret=add(ret,Num<t?dp[pre][0]:dp[pre][1]);
		Num^=t;
		ar[cnt]^=t;
		for(int i=cnt-1;i&&ar[i]>ar[i+1];i--)swap(ar[i],ar[i+1]);
	}
}

int main()
{
	n=getint(),m=getint(),C=getint();
	for(int i=0;i<n;i++)a[i]=getint(),pos[i]=i,lg[1<<i]=i;
	sort(pos,pos+n,cmp);sort(a,a+n);
	for(int i=0;i<n;i++)id[pos[i]]=i;
	while(m--)
	{
		int u=id[getint()-1],v=id[getint()-1];
		fe[(1<<u)|(1<<v)]=1;
	}
	pw2[0]=1;for(int i=1;i<=60;i++)pw2[i]=pw2[i-1]*2;
	for(int i=0;i<(1<<n);i++)sz[i]=sz[i>>1]+(i&1);
	for(int i=0;i<n;i++)for(int j=0;j<(1<<n);j++)if((j>>i)&1)fe[j]|=fe[j^(1<<i)];
	for(int s=1;s<(1<<n);s++)
	{
		coef[s]=!fe[s];
		for(int t=s&(s-1);t;t=(t-1)&s)if(t&s&(-s))coef[s]=add(coef[s],MOD-coef[t]*(!fe[s^t]));
	}
	for(int i=1;i<(1<<n);i++)if(!(sz[i]&1))coef[i]=1ll*coef[i]*add(a[lg[i&(-i)]]%MOD,1)%MOD;
	fn[0]=!C;
	for(int i=1;i<(1<<n);i++)fn[i]=solve(i);
	pw3[0]=N=1;for(int i=1;i<=n;i++)pw3[i]=N=N*3;
	for(int i=1;i<(1<<n);i++)st[i]=st[i>>1]*3+(i&1);
	for(int i=1;i<(1<<n);i++)if(sz[i]&1)st[i]+=pw3[lg[i&(-i)]];
	f[0]=1;
	for(int s=0;s<N;s++)if(f[s])
	{
		int t=0,fp=0;
		for(int i=0;i<n;i++)if(s/pw3[i]%3==0)t|=1<<i,fp?0:fp=1<<i;
		if(t)
		{
			int r=t^fp;
			for(int p=r;;p=(p-1)&r)
			{
				int now=s+st[fp|p];
				f[now]=add(f[now],1ll*f[s]*coef[fp|p]%MOD);
				if(!p)break;
			}
		}
		else
		{
			for(int i=0;i<n;i++)if(s/pw3[i]%3==2)t|=1<<i;
			ans=add(ans,1ll*f[s]*fn[t]%MOD);
		}
	}
	printf("%d\n",ans);
}

posted @ 2020-05-21 14:54  Izayoi_Doyo  阅读(225)  评论(0编辑  收藏  举报