题解:P10613 [PA2008] Cliquers
OldDriverTree · · 题解
前言
划分数的根号分治 + DP 板子题。
不太懂本题这个输出
目前不知道这个东西用古代猪文那个 trick 后模数为质数有没有什么特殊做法。
Solution
首先注意到
有一个显然的 DP:设
转移就是
但是直接这样做时间复杂度是
对于大于等于
考虑对这个
最后由于求的是
总时间复杂度就为
Code
//when you use vector or deque,pay attention to the size of it.
//by OldDirverTree
#include<bits/stdc++.h>
//#include<atcoder/all>
#define P pair<int,int>
#define int long long
#define mid (l+r>>1)
using namespace std;
//using namespace atcoder;
const int N=2e5+1,mod=1e9-401;
int n,m,B,res,ans=1,f[N],g[N];
int read() {
int x=0; bool f=true; char c=0;
while (!isdigit(c) ) f&=(c!='-'),c=getchar();
while (isdigit(c) ) x=(x<<3)+(x<<1)+(c&15),c=getchar();
return f?x:-x;
}
main()
{
n=read(),m=read(),B=sqrt(n),f[0]=g[0]=1;
for (int i=1;i<B;i++) for (int j=i;j<=n;j++)
f[j]=(f[j]+f[j-i])%(mod-1); res=f[n];
for (int i=1;i<=n/B;i++) {
for (int j=i;j<=n;j++) g[j]=(g[j]+g[j-i])%(mod-1);
for (int j=0;j<=n-i*B;j++) res=(res+f[j]*g[(n-j)-i*B]%(mod-1) )%(mod-1);
}
while (res) {
if (res&1) ans=ans*m%mod;
m=m*m%mod,res>>=1;
}
printf("%lld",ans);
return 0;
}