連在一起的幻想鄉
阿新 • • 發佈:2018-12-10
題目大意:求個點的無向簡單連通圖邊數平方的和,。 題解: 考慮dp,設分別表示所有個點無向簡單圖的邊數的次,次,次方和,記,易知: 最後一個可以考慮對某個函式求導乘以x,再求導然後乘以x,然後令x=1即可;事實上可以推廣到的情況。 令表示個點無向簡單連通圖的邊數的次,次,次方和,則: 這個也可以推廣到的情況。 複雜度。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define N 2010
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define lint long long
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
int c[N][N],m[N],f0[N],f1[N],f2[N],h0[N],h1[N],h2[N],mod;
inline int fast_pow(int x,int k,int ans=1) { for(;k;k>>=1,x=(lint)x*x%mod) (k&1)?ans=(lint)ans*x%mod:0;return ans; }
int main()
{
int n;scanf("%d%d",&n,&mod);rep(i,1,n) m[i]=i*(i-1)/2;
rep(i,1,n) h0[i]=fast_pow(2,m[i]),(i>1?h1[i]=(lint)m[i]*fast_pow(2,m[i]-1)%mod:0),
(i>2?h2[i]=m[i]*(m[i]+1ll)%mod*fast_pow(2,m[i]-2)%mod:0);
h1[1]=0,h2[1]=0,h2[2]=1,f0[1]=1,f1[1]=0,f2[1]=0;rep(i,0,n) c[i][0]=1;
rep(i,1,n) rep(j,1,i) c[i][j]=c[i-1][j]+c[i-1][j-1],(c[i][j]>=mod?c[i][j]-=mod:0);
rep(i,2,n)
{
lint w0=0,w1=0,w2=0;
rep(j,1,i-1) w0+=(lint)c[i-1][j-1]*f0[j]%mod*h0[i-j]%mod,
w1+=((lint)f1[j]*h0[i-j]+(lint)f0[j]*h1[i-j])%mod*c[i-1][j-1]%mod,
w2+=((lint)f2[j]*h0[i-j]+2ll*f1[j]*h1[i-j]+(lint)f0[j]*h2[i-j])%mod*c[i-1][j-1]%mod;
f0[i]=h0[i]-(int)(w0%mod),(f0[i]<0?f0[i]+=mod:0),
f1[i]=h1[i]-(int)(w1%mod),(f1[i]<0?f1[i]+=mod:0),
f2[i]=h2[i]-(int)(w2%mod),(f2[i]<0?f2[i]+=mod:0);
}
return !printf("%d\n",f2[n]);
}