# bzoj4197:[Noi2015]寿司晚宴

### 传送门

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
char ch; bool ok;
for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
}
#define rg register
const int maxn=510,maxm=(1<<8)+10;
int n,mx=1<<8,d[8]={2,3,5,7,11,13,17,19};
long long ans,p,f1[maxm][maxm],f2[maxm][maxm],g[maxm][maxm];
struct oo{int x,y;}a[maxn];
void prepare(int x)
{
int now=x+1;a[x].y=-1;
for(rg int i=0;i<8;i++)
if(!(now%d[i]))
{
a[x].x|=(1<<i);
while(!(now%d[i]))now/=d[i];
}
if(now!=1)a[x].y=now;
}
bool cmp(oo a,oo b){return a.y<b.y;}
int main()
{
for(rg int i=1;i<n;i++)prepare(i);
sort(a+1,a+n,cmp),g[0][0]=1;
for(rg int i=1;i<n;i++)
{
if(i==1||a[i].y!=a[i-1].y||a[i].y==-1)memcpy(f1,g,sizeof g),memcpy(f2,g,sizeof g);
for(rg int j=mx-1;j>=0;j--)
for(rg int k=mx-1;k>=0;k--)
if(!(j&k))
{
if(!(a[i].x&j))f2[j][k|a[i].x]=f2[j][k]+f2[j][k|a[i].x]>=p?f2[j][k]+f2[j][k|a[i].x]-p:f2[j][k]+f2[j][k|a[i].x];
if(!(a[i].x&k))f1[j|a[i].x][k]=f1[j][k]+f1[j|a[i].x][k]>=p?f1[j][k]+f1[j|a[i].x][k]-p:f1[j][k]+f1[j|a[i].x][k];
}
if(i==n-1||a[i].y!=a[i+1].y||a[i].y==-1)
{
for(rg int j=mx-1;j>=0;j--)
for(rg int k=mx-1;k>=0;k--)
if(!(j&k))g[j][k]=(((f1[j][k]+f2[j][k]-g[j][k])%p)+p)%p;
}
}
for(rg int j=mx-1;j>=0;j--)
for(rg int k=mx-1;k>=0;k--)
if(!(j&k))ans=ans+g[j][k]>=p?ans+g[j][k]-p:ans+g[j][k];
printf("%lld\n",ans);
}
posted @ 2019-03-24 21:56 蒟蒻--lichenxi 阅读(...) 评论(...) 编辑 收藏