CF917D Stranger Trees

Link
众所周知Kirchhoff定理中的边权可以是多项式。
直接NTT的复杂度是\(O(n^4\log n)\)
\(n\)个值进去算然后快速插值Lagrange插值或者Gauss消元是\(O(n^4)\)的。

#include<bits/stdc++.h>
#define LL long long
using namespace std;
namespace IO
{
    char ibuf[(1<<21)+1],obuf[(1<<21)+1],st[15],*iS,*iT,*oS=obuf,*oT=obuf+(1<<21);
    char Get() { return (iS==iT? (iT=(iS=ibuf)+fread(ibuf,1,(1<<21)+1,stdin),(iS==iT? EOF:*iS++)):*iS++); }
    void Flush() { fwrite(obuf,1,oS-obuf,stdout),oS=obuf; }
    void Put(char x) { *oS++=x; if(oS==oT) Flush(); }
    int read() { int x=0; char ch=Get(); while(ch>'9'||ch<'0') ch=Get(); while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=Get(); return x; }
    void write(int x) { int top=0; if(!x) Put('0'); while(x) st[++top]=(x%10)+48,x/=10; while(top) Put(st[top--]); Put(' '); }
}
using namespace IO;
const int N=103,P=1000000007;
int a[N][N],c[N][N],b[N];
int power(int a,int k=P-2){int r=1;for(;k;k>>=1,a=1ll*a*a%P)if(k&1)r=1ll*a*r%P;return r;}
void swap(int &x,int &y){x^=y^=x^=y;}
int inc(int a,int b){a+=b;return a>=P? a-P:a;}
int dec(int a,int b){a-=b;return a<0? a+P:a;}
int det(int n)
{
    int ans=1;
    for(int i=1,j,k,Inv,num;i<=n;++i)
    {
        Inv=power(c[i][i]);
        for(j=i+1;j<=n;++j)
        {
            num=1ll*c[j][i]*Inv%P;
            for(k=i;k<=n;++k) c[j][k]=dec(c[j][k],1ll*num*c[i][k]%P);
        }
        ans=1ll*ans*c[i][i]%P;
        if (!c[i][i]) break;
    }
    return ans;
}
int main()
{
    int n=read();
    for(int i=1,x,y;i<n;++i) x=read(),y=read(),a[x][y]=a[y][x]=1;
    for(int k=1,i,j;k<=n;++k)
    {
        memset(c,0,sizeof c);
        for(i=1;i<=n;++i) for(j=1;j<=n;++j) if(i^j) if(a[i][j]) c[i][j]=P-k,c[i][i]+=k; else c[i][j]=P-1,c[i][i]+=1;    
        b[k]=det(n-1);
    }
    for(int i=1,j;i<=n;++i)
    {
        c[i][1]=1;
        for (j=2;j<=n;++j) c[i][j]=1ll*c[i][j-1]*i%P;
    }
    for(int i=1,j,k,Inv,num;i<=n;++i)
    {
        Inv=power(c[i][i]);
        for(j=1;j<=n;++j)
            if(i^j)
        {
        num=1ll*c[j][i]*Inv%P;
        for(k=i;k<=n;++k) c[j][k]=dec(c[j][k],1ll*num*c[i][k]%P);
        b[j]=dec(b[j],1ll*num*b[i]%P);
        }
    }
    for(int i=1;i<=n;++i) write(1ll*b[i]*power(c[i][i])%P);
    return Flush(),0;
}

猜你喜欢

转载自www.cnblogs.com/cjoierShiina-Mashiro/p/12239188.html