title
Description
Given a \ (n-\) weighted points undirected complete graph, find all weights spanning tree \ (K \) th power sum.
The definition of a tree weights, weights and all its edges.
Since the answer may be large, please output the answer to (998 244 353 \) \ result modulo.
analysis
Reference: hec0411 .
The answer probably is listed first equation:
Set \ (E \) is the edge set of a spanning tree we enumeration.
\ [Ans = \ sum_ {E } (\ sum_ {i \ in E} w_i) ^ k \\ = \ sum_E \ prod_ {i \ in E} \ binom {k} {a_i} w_i ^ {a_i} [\ sum_ {i \ in E} a_i = k] \\ = \ sum_E \ frac {1} {k!} \ prod_ {i \ in E} \ frac {1} {a_i!} w_i ^ {a_i} [\ sum_ {i \ in E} a_i = k] \]
Kirchhoff matrix can be determined:
\ [\ sum_ {E} \ {prod_ I \ E} in W_i \]
For the above equation, we found that each side is actually a polynomial:
\ [{!} I W (X) = \ sum_ {I} = 0 ^ K \ FRAC. 1} W {I ^ \]
So the final answer can be found in polynomial terms is probably \ (the n-* k \) .
So we can fit into larger than \ (n * k + 1 \ ) values into the calculated value corresponding to the tree theorems of matrix, and then using the Lagrange interpolation big brother of count \ (K \) coefficients of terms, I think it seems Gaussian elimination do just fine.
Time complexity is about: \ (O (n-4K ^) \) .
code
#include<bits/stdc++.h>
typedef long long ll;
const int maxn=31,mod=998244353;
typedef ll lar1[maxn*maxn];
typedef ll lar2[maxn][maxn];
namespace IO
{
char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
char Out[1<<24],*fe=Out;
inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }
template<typename T>inline void write(T x,char str)
{
if (!x) *fe++=48;
if (x<0) *fe++='-', x=-x;
T num=0, ch[20];
while (x) ch[++num]=x%10+48, x/=10;
while (num) *fe++=ch[num--];
*fe++=str;
}
}
using IO::read;
using IO::write;
inline ll Quick_power(ll a,ll b)
{
ll ans=1;
while (b)
{
if (b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
inline ll Gauss(ll a[maxn][maxn],int n)
{
ll ans=1;
for (int k=2; k<=n; ++k)
{
for (int i=k; i<=n; ++i)
if (a[i][k])
{
if (k^i) ans=ans*(mod-1)%mod, std::swap(a[k],a[i]);
break;
}
ans=ans*a[k][k]%mod;
ll INV=Quick_power(a[k][k],mod-2);
for (int i=k+1; i<=n; ++i)
{
ll tmp=INV*a[i][k]%mod;
for (int j=k; j<=n; ++j) a[i][j]=(a[i][j]-tmp*a[k][j]%mod+mod)%mod;
}
}
return ans;
}
int m;
lar1 f,h,fac,inv;
inline void Add(int x)
{
for (int i=m; i>=0; --i)
{
h[i]=h[i]*(mod-x)%mod;
if (i) (h[i]+=h[i-1])%=mod;
}
}
inline void Del(int x)
{
for (int i=0; i<=m; ++i)
{
if (i) h[i]=h[i]-h[i-1]+mod;
h[i]=h[i]*Quick_power(mod-x,mod-2)%mod;
}
}
lar2 w,val,a;
ll g[maxn][maxn][maxn];
int main()
{
int n,k;read(n);read(k);
m=n*k+3;
fac[0]=1;
for (int i=1; i<=m; ++i) fac[i]=fac[i-1]*i%mod;
inv[m]=Quick_power(fac[m],mod-2);
for (int i=m-1; i>=0; --i) inv[i]=inv[i+1]*(i+1)%mod;
for (int i=1; i<=n; ++i)
for (int j=1; j<=n; ++j) read(w[i][j]);
for (int i=1; i<=n; ++i)
for (int j=i+1; j<=n; ++j)
for (int t=0; t<=k; ++t) g[i][j][t]=Quick_power(w[i][j],t)*inv[t]%mod;
for (int x=1; x<=m; ++x)
{
for (int i=1; i<=n; ++i)
for (int j=i+1; j<=n; ++j)
{
val[i][j]=0;
ll now=1;
for (int t=0; t<=k; ++t) (val[i][j]+=g[i][j][t]*now)%=mod, now=now*x%mod;
}
memset(a,0,sizeof(a));
for (int i=1; i<=n; ++i)
for (int j=i+1; j<=n; ++j)
{
a[i][i]+=val[i][j], a[j][j]+=val[i][j];
a[i][j]-=val[i][j], a[j][i]-=val[i][j];
}
for (int i=1; i<=n; ++i)
for (int j=1; j<=n; ++j) a[i][j]=(a[i][j]%mod+mod)%mod;
f[x]=Gauss(a,n);
}
h[0]=1;
for (int i=1; i<=m; ++i) Add(i);
ll ans=0;
for (int i=1; i<=m; ++i)
{
Del(i);
ll now=1;
for (int j=1; j<=m; ++j)
if (i^j) now=now*(i-j)%mod;
now=Quick_power(now%mod+mod,mod-2);
ans=(ans+now*h[k]%mod*f[i])%mod;
Add(i);
}
write(ans*fac[k]%mod,'\n');
IO::flush();
return 0;
}