记录编号 309318 评测结果 AAAAAAAAAA
题目名称 [NOI 2015]寿司晚宴 最终得分 100
用户昵称 Gravatar甘罗 是否通过 通过
代码语言 C++ 运行时间 1.849 s
提交时间 2016-09-19 13:56:21 内存使用 1.06 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 510
using namespace std;

int n,i,j,P=0,t;
long long ans;
int p[10]={2,3,5,7,11,13,17,19,0,0};
int f[300][300];   //f[i][j]表示A拿了i的质因数,B拿了j的质因数的方案数
int g[2][300][300];
struct Marvolo{
	int x,y;   //x表示该数的质因数的二进制,1表示有,0表示无
}a[N];   //y表示大于19的质因数包含情况

inline bool cmp(const Marvolo a,const Marvolo b){return (a.y!=b.y)?a.y<b.y:a.x<b.x;}
inline void DP(){
	int i=0,j=0,k=0,all=1<<8;
	sort(a+2,a+n+1,cmp);	f[0][0]=1;
	for (i=2;i<=n;i++){
		if (i==2||a[i].y==1||a[i].y!=a[i-1].y){
			memcpy(g[0],f,sizeof(f));	memcpy(g[1],f,sizeof(f));}
			for (j=all-1;j>=0;j--)
				for (k=all-1;k>=0;k--){
				if (!(j&a[i].x)) g[1][j][k|a[i].x]=(g[1][j][k|a[i].x]+g[1][j][k])%P;
                if (!(k&a[i].x)) g[0][j|a[i].x][k]=(g[0][j|a[i].x][k]+g[0][j][k])%P;
			}
		if (i==n||a[i].y==1||a[i].y!=a[i+1].y)	{
			for (j=0;j<all;j++)
				for (k=0;k<all;k++)
					f[j][k]=((g[0][j][k]+g[1][j][k]-f[j][k])%P+P)%P;
		}
	}
	for (i=0;i<all;i++)
		for (j=0;j<all;j++)
			if (!(i&j))	ans=(ans+f[i][j])%P;
	return;
}

int main(){
	freopen("dinner.in","r",stdin);
	freopen("dinner.out","w",stdout);	
	scanf("%d%d",&n,&P);
	for (i=2;i<=n;i++){
		t=i;
		for (j=0;j<=7;j++)
		if (!(t%p[j]))	{
			a[i].x|=1<<j;	for (;!(t%p[j]);t/=p[j]);
		}
		a[i].y=t;
	}
	DP();	printf("%lld\n",ans);
	return 0;
}