JZOJ6675. 【2020.05.30省选模拟】交通网络
Description
Solution
O(n^4)
- 直接放弃思考矩阵树即可过,获得23分。
O(n^2)
- 考虑先枚举一些特殊边,将n个点分成m个联通块,再用prufer序列计算这个完全图的方案数:
- 考虑prufer序列中的一个值代表了一条边,且长度为,那么连边的时候就可以有n个顶点,即。又因为prufer序列出现次数为度数-1,所以每一个联通块只考虑到了度数-1次顶点的选择,所以还有的贡献没有计算到。
- 直接DP即可O(n^2)
O(nlogn)
- 因此确定m个联通快的方案数就是上面的东西乘上。
- 但是这是至少条特殊边的方案数,设至少n条方案为,则答案要求的恰好,有.
- 则,卷积即可求出对应位置的答案。
O(n)
- 我们先考虑为权值怎么办,那么相当于任意一个恰好x条的都会被它的任意一个子集算一次,答案实际上就是。
- 再考虑权值为怎么做,,后者就是。
- 原本计算时,是,那么现在这个答案显然就是
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define ll long long
#define mo 998244353
#define maxn 1000005
using namespace std;
int n,i;
ll fct[maxn],invf[maxn],ans,f[maxn],mul[maxn];
ll ksm(ll x,ll y){
ll s=1;
for(;y;y/=2,x=x*x%mo) if (y&1)
s=s*x%mo;
return s;
}
ll C(int n,int m){return fct[n]*invf[n-m]%mo*invf[m]%mo;}
int main(){
scanf("%d",&n);
fct[0]=1;for(i=1;i<=2*n;i++) fct[i]=fct[i-1]*i%mo;
invf[2*n]=ksm(fct[2*n],mo-2);
for(i=2*n-1;i>=0;i--) invf[i]=invf[i+1]*(i+1)%mo;
mul[0]=1;for(i=1;i<=n;i++) mul[i]=mul[i-1]*n%mo;
f[n-1]=1;for(i=2;i<=n;i++) f[n-i]=C(n+i-1,2*i-1)*mul[i-2]%mo;
for(i=0;i<n;i++) ans+=f[i]*i%mo;
printf("%lld",ans*2%mo);
}