高质量好题:[THUPC2019]找树

Link

原题目可以转换到求是否存在权值为 \(x\) 的生成树。这里求法就不赘述了。

考虑到暴力求解行列式的方法 \(Det(T)=\sum(-1)^{k}\prod F_{p_{i}}\)

如果按照这种做法,实际上可以先 \(FWT\) 一遍,最后得到的结果再 \(IFWT\) 回来,

\(Det(T)=IFWT(Det(FWT(T)))\) 。(此处 \(FWT\) 之后的乘法也要对应变换)

下面将给出简单证明。


引理: \(FWT(A+B)=FWT(A)+FWT(B)\)

证明:\(FWT(A)+FWT(B)=\sum_{i}x^{i}\sum_{j|i}a_{i}+\sum_{i}x^{i}\sum_{j|i}b_{i}=\sum_{i}x^{i}\sum_{j|i}a_{i}+b_{i}=FWT(A+B)\)

以下是 \(Det(T)=IFWT(Det(FWT(T)))\) 的证明

\[\begin{aligned} Det(T)&=\sum(-1)^{k}IFWT(\sum_{i=1}x^{i}\prod FWT(F_{p_{j}})[x^{i}])\\ &=IFWT(\sum_{}(-1)^k\sum_{i=1}x^{i}\prod FWT(F_{p_{j}})[x^{i}]\\ FWT(Det(T))&=\sum(-1)^{k}\prod FWT(F_{p_j})\\ &=Det(FWT(T))\\ IFWT(FWT(Det(T)))&=IFWT(Det(FWT(T)))=Det(T) \end{aligned} \]

\(G=FWT(T)\) ,那么可以发现, \(Det(G)[x^n]=Det( G[x^n]x^n)[x^n]\) 写的比较鬼畜,就是指G的每一项之间都是相互独立的


证明:

\[\begin{aligned} Det(G)&=\sum(-1)^k\sum_{i=1}x^{i}\prod F_{p_j}[x^i]\\ &=\sum_{i=1}x^{i}\sum_{p}(-1)^{k}\prod F_{p_j}[x^i]\\ \end{aligned} \]

显然每一位之间都是独立的。


根据这两个性质,就可以得到 \(Det(T)=IFWT(\sum_{i=1}Det(FWT(T)[x^i]))\)

时间复杂度 \(O(n^2 2^ww+n^32)\)

Code
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define ri register int
#define ll long long
#define ui unsigned int
il ll read(){
    bool f=true;ll x=0;
    register char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-') f=false;ch=getchar();}
    while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    if(f) return x;
    return ~(--x);
}
il void write(const ll &x){if(x>9) write(x/10);putchar(x%10+'0');}
il void print(const ll &x) {x<0?putchar('-'),write(~(x-1)):write(x);putchar('\n');}
il ll max(const ll &a,const ll &b){return a>b?a:b;}
il ll min(const ll &a,const ll &b){return a<b?a:b;}
const ll mod=998244353,inv2=(mod+1)/2;
il ll add(ll x,ll y){return (x+=y)<mod?x:x-mod;}
il ll dec(ll x,ll y){return (x-=y)<0?x+mod:x;}
il ll ksm(ll d,ll tim){
    ll rest=1;
    while(tim){
        if(tim&1) rest=rest*d%mod;
        d=d*d%mod;
        tim>>=1;
    }
    return rest;
}
char op[20];
void FWT(int limit,int *f,int flag){
    for(ri l=1,t=0;l<limit;l<<=1,++t)
        for(ri i=0;i<limit;i+=(l<<1))
            for(ri j=0;j<l;++j){
                if(op[t]=='|'){
                    if(flag==1) f[i+j+l]=add(f[i+j+l],f[i+j]);
                    else f[i+j+l]=dec(f[i+j+l],f[i+j]);
                }
                if(op[t]=='&'){
                    if(flag==1) f[i+j]=add(f[i+j],f[i+j+l]);
                    else f[i+j]=dec(f[i+j],f[i+j+l]);
                }
                if(op[t]=='^'){
                    int tmp=f[i+j+l];
                    if(flag==1) f[i+j+l]=dec(f[i+j],f[i+j+l]),f[i+j]=add(f[i+j],tmp);
                    else f[i+j+l]=dec(f[i+j],f[i+j+l])*inv2%mod,f[i+j]=add(f[i+j],tmp)*inv2%mod;
                }
            }
}
const int MAXN=75;
int a[MAXN][MAXN],n,w,m,g[MAXN][MAXN][1<<12],f[1<<12];
int det(){
    int ans=1;
    for(ri i=1;i<n;++i){
        if(!a[i][i]){
            for(ri j=i+1;j<n;++j){
                if(a[j][i]){
                    swap(a[j],a[i]);
                    ans=mod-ans;
                    break;
                }
            }
        }
        if(!a[i][i]) return 0;
        int  inv=ksm(a[i][i],mod-2);
        for(ri j=i+1;j<n;++j){
            ll d=1ll*a[j][i]*inv%mod;
            for(ri k=i;k<n;++k) a[j][k]=dec(a[j][k],d*a[i][k]%mod);
        }
    }
    for(ri i=1;i<n;++i) ans=1ll*ans*a[i][i]%mod;
    return ans;
}
int main(){
    // freopen("255.txt","r",stdin);
    // freopen("1.out","w",stdout);
    n=read(),m=read();
    scanf("%s",op);w=strlen(op);
    for(ri i=1;i<=m;++i){
        int u=read(),v=read(),w=read();
        g[u][u][w]++,g[v][v][w]++;
        g[u][v][w]=dec(g[u][v][w],1),g[v][u][w]=dec(g[v][u][w],1);
    }
    for(ri i=1;i<=n;++i)
        for(ri j=1;j<=n;++j)
            FWT(1<<w,g[i][j],1);
    for(ri x=0;x<(1<<w);++x){
        for(ri i=1;i<=n;++i){
            for(ri j=1;j<=n;++j){
                a[i][j]=g[i][j][x];
            }
        }
        f[x]=det();
    }
    FWT(1<<w,f,-1);
    int ans=-1;
    for(ri i=(1<<w)-1;~i;--i) 
        if(f[i]) {ans=i;break;}
    print(ans);
    return 0;
}
posted @ 2021-08-12 20:44  krimson  阅读(50)  评论(0编辑  收藏  举报