Description
Solution
设将n划分为若干个无序正整数之和的方案数为s
可以看出答案就是
ms
m
s
令
n′=n−−√
n
′
=
n
分成两个问题,一个是用小于等于
n′
n
′
的数来拼和用大于
n′
n
′
的数来拼,最后再卷积到一起
小于等于
n′
n
′
的部分就是一个完全背包问题
大于
n′
n
′
的部分,总的选择个数不会超过
n′
n
′
可以考虑这样一个DP,每次要么加入一个
n′+1
n
′
+
1
,要么把以前加入所有的数都+1
这样就在 O(nn−−√) O ( n n ) 的复杂度解决了
Code
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <iostream>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define N 200005
#define M 450
#define LL long long
#define mo 999999599
using namespace std;
LL f[N],g[2][N],h[N];
int bz[2][N];
int n,m;
LL ksm(LL k,LL n)
{
LL s=1;
for(;n;n>>=1,k=k*k%mo) if(n&1) s=s*k%mo;
return s;
}
int main()
{
cin>>n>>m;
f[0]=1;
int n1=sqrt(n);
fo(i,1,n1)
{
fo(j,i,n)
f[j]=(f[j]+f[j-i])%(mo-1);
}
g[0][0]=1;
int i1=0;
LL s=0;
fo(i,1,n1)
{
i1=1-i1;
fo(j,(n1+1)*i,n)
{
if(bz[i1][j-i]!=i) bz[i1][j-i]=i,g[i1][j-i]=0;
if(bz[1-i1][j-n1-1]!=i-1) bz[1-i1][j-n1-1]=i-1,g[1-i1][j-n1-1]=0;
g[i1][j]=(g[i1][j-i]+g[1-i1][j-n1-1])%(mo-1);
bz[i1][j]=i;
h[j]=(h[j]+g[i1][j])%(mo-1);
}
}
h[0]=1;
fo(i,0,n)
s=(s+f[i]*h[n-i]%(mo-1))%(mo-1);
printf("%lld\n",ksm(m,s));
}