标签:
因为每个数只有一个大于根号n的质因子,所以我们把每个数拆成一个大于根号n的质因子乘以一个数的形式,对于大于根号n的质因子相同的数,我们放到一起处理注:这道题指数只需要存到19,因为23*29>500
能想出这道题的人都好厉害呀
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> using namespace std; struct yts { int p,a; }q[510]; bool cmp(yts x,yts y) { return x.p<y.p; } int pri[10]={2,3,5,7,11,13,17,19}; int dp[2][1<<8][1<<8],f[1<<8][1<<8]; int n,m,mod,tot; void calc(int x) { tot++; for (int i=0;i<=7;i++) if (x%pri[i]==0) { while (x%pri[i]==0) x/=pri[i]; q[tot].a|=(1<<i); } q[tot].p=x; } int main() { scanf("%d%d",&n,&mod); for (int i=2;i<=n;i++) calc(i); sort(q+1,q+tot+1,cmp); f[0][0]=1; for (int i=1;i<=tot;i++) { if (q[i].p==1 || q[i].p!=q[i-1].p) for (int x=0;x<(1<<8);x++) for (int y=0;y<(1<<8);y++) dp[0][x][y]=dp[1][x][y]=f[x][y]; for (int x=(1<<8)-1;x>=0;x--) for (int y=(1<<8)-1;y>=0;y--) { if ((y&q[i].a)==0) dp[0][x|q[i].a][y]=(dp[0][x|q[i].a][y]+dp[0][x][y])%mod; if ((x&q[i].a)==0) dp[1][x][y|q[i].a]=(dp[1][x][y|q[i].a]+dp[1][x][y])%mod; } if (q[i].p==1 || i==n || q[i].p!=q[i+1].p) for (int x=0;x<(1<<8);x++) for (int y=0;y<(1<<8);y++) f[x][y]=((long long)dp[0][x][y]+dp[1][x][y]-f[x][y]+mod)%mod; } int ans=0; for (int i=0;i<(1<<8);i++) for (int j=0;j<(1<<8);j++) if ((i&j)==0) ans=(ans+f[i][j])%mod; printf("%d\n",ans); return 0; }
标签:
原文地址:http://blog.csdn.net/u012288458/article/details/51360737