UOJ 129/BZOJ 4197 寿司晚宴 状压DP
//By SiriusRen #include <cstdio> #include <algorithm> using namespace std; const int N=555; struct Node{int a,p;}node[N]; bool operator<(Node a,Node b){return a.p<b.p;} char pr[]={2,3,5,7,11,13,17,19}; int n,p,f[N][N],dp[N][N][2],ans; void div(int x){ int cpy=x; for(int i=0;i<8;i++) if(!(x%pr[i])){ while(x%pr[i]==0)x/=pr[i]; node[cpy].a|=1<<i; } node[cpy].p=x; } int main(){ scanf("%d%d",&n,&p); for(int i=2;i<=n;i++)div(i); sort(node+2,node+1+n),f[0][0]=1; for(int i=2;i<=n;i++){ if(node[i].p==1||node[i].p!=node[i-1].p) for(int j=0;j<256;j++) for(int k=0;k<256;k++) dp[j][k][0]=dp[j][k][1]=f[j][k]; for(int j=255;~j;j--) for(int k=255;~k;k--){ if(!(node[i].a&k))(dp[j|node[i].a][k][0]+=dp[j][k][0])%=p; if(!(node[i].a&j))(dp[j][k|node[i].a][1]+=dp[j][k][1])%=p; } if(node[i].p==1||node[i].p!=node[i+1].p) for(int j=255;~j;j--) for(int k=255;~k;k--) f[j][k]=((dp[j][k][0]+dp[j][k][1]-f[j][k])%p+p)%p; } for(int i=0;i<256;i++)for(int j=0;j<256;j++)if(!(i&j))(ans+=f[i][j])%=p; printf("%d\n",ans); }