题解:P12445 [COTS 2025] 数好图 / Promet
Solution
我做这个题,花了将近 2 个小时……如此水平,如何 NOI!/ll
不过克罗地亚国家队在这道题上得分
考虑
考虑让
那么直接施加容斥。设
在
对于
将点划分为
记
对于每个点,我们往前连边。
发现什么?
因此我们可以 DP 求出所有的贡献之和,然后将
整体时间复杂度为
#include<bits/stdc++.h>
#define int long long
#define ffor(i,a,b) for(int i=(a);i<=(b);i++)
#define roff(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int MAXN=2000+10;
int n,MOD,dp[MAXN][MAXN],C[MAXN][MAXN],pw[MAXN*MAXN],ans[MAXN];
int mul[MAXN][MAXN],f[MAXN][MAXN],g[MAXN];
signed main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n>>MOD;
pw[0]=1; ffor(i,1,n*n) pw[i]=pw[i-1]*2%MOD;
ffor(i,0,n) {
C[i][0]=1;
ffor(j,1,i) C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
}
dp[1][0]=1;
ffor(i,2,n) ffor(j,0,i-1) {
int mul=dp[i-1][j];
if(j) mul=(mul+dp[i-1][j-1])%MOD;
dp[i][j]=mul*(pw[i-j-1]-1)%MOD;
}
ffor(i,2,n) ffor(j,0,i) g[i]=(g[i]+dp[i][j]*(1-2*(j&1)))%MOD;
mul[n][0]=1;
roff(i,n-1,2) ffor(j,0,n) {
mul[i][j]=mul[i+1][j];
if(j) mul[i][j]=(mul[i][j]+mul[i+1][j-1]*pw[n-i])%MOD;
}
f[1][0]=1;
ffor(i,1,n) ffor(j,(i==1),n-i) {
f[i][j]=f[i-1][j],ans[i]=(ans[i]+mul[2][n-i-j]*f[i][j])%MOD;
if(j) f[i][j]=(f[i][j]+f[i][j-1]*(pw[i+j-1]-1))%MOD;
}
ffor(i,2,n) ans[i]=ans[i]*g[i]%MOD;
ans[0]=pw[n*(n-1)/2];
ffor(i,2,n) ans[0]=(ans[0]-ans[i])%MOD;
ffor(i,0,n) cout<<(ans[i]%MOD+MOD)%MOD<<' ';
return 0;
}