CF1174E
非常好题目,使我的大脑旋转(?)
还是一样,介绍思路。
既然题目让我们计算
但是还需要知道有没有其他可能的
综上,得出结论:
对于这两个数,他们有一个性质:因数不会太多。也就意味着,
于是可以考虑 dp,并存下来当前选了几个数,以及前缀
其实状态两维就够。
code:
点击查看代码
int n,m,k,a[N],b[N],dp[N][47];
il int Mod(int x,int y){return x+y>=mod?x+y-mod:x+y;}
int solve(int x){
k=0,mems(b,0);
drep(i,n,1)if(x%i==0)a[++k]=i,b[i]=k;
mems(dp,0),dp[1][1]=1;
rep(i,2,n){
rep(j,1,k){
dp[i][j]=1ll*dp[i-1][j]*(n/a[j]-i+1)%mod;
if(a[j]*2<=n&&b[a[j]*2])dp[i][j]=Mod(dp[i][j],1ll*dp[i-1][b[a[j]*2]]*(n/a[j]-n/(a[j]*2))%mod);
if(a[j]*3<=n&&b[a[j]*3])dp[i][j]=Mod(dp[i][j],1ll*dp[i-1][b[a[j]*3]]*(n/a[j]-n/(a[j]*3))%mod);
}
}
return dp[n][k];
}
void Yorushika(){
scanf("%d",&n),m=__lg(n);
int x=1<<__lg(n);
if(x/2*3<=n)printf("%d\n",Mod(solve(x),solve(x/2*3)));
else printf("%d\n",solve(x));
}
signed main(){
int t=1;
// scanf("%d",&t);
while(t--)
Yorushika();
}