• [省选联考 2020 A 卷] 作业题


    给定一张 (n) 个点 (m) 条边的带边权的无向图,定义一棵生成树 (T) 的价值为:

    [(sum_{i=1}^{n-1}w_{e_i}) imes gcd(w_{e_1}, w_{e_2},cdots,w_{e_{n-1}}) ]

    其中 (w_{e_i})(T) 中的边。要求求出所有生成树的价值和。(1 leq n leq 30 , 1 leq m leq frac{n(n-1)}{2} , 1 leq w_i leq 152501) ,无重边自环。


    怎么想到的啊。。。
    首先如果 (w_i) 全相同,那就直接 ( ext{matrix}) 定理求一下生成树个数即可。但现在 (w_i) 不相同。
    化一下式子:

    [egin{aligned} (sum_{i=1}^{n-1}w_{e_i}) imes gcd(w_{e_1}, w_{e_2},cdots,w_{e_{n-1}}) \=(sum_{i=1}^{n-1}w_i{e_i}) imes sum_{d|w_1, d|w_2, cdots ,d|w_{n-1}}varphi(d) \=sum_{d=1}varphi(d) sum_{d|w_1,d|w_2,cdots,w_{n-1}}sum_{i=1}^{n-1}w_i end{aligned} ]

    现在就只需要对于每个 (d) ,求出所有边权是 (d) 的倍数的边构成的子图的答案。考虑对每条边计算它的贡献,也就是对于这条边来说,有多少棵包含它的生成树。本来如果 (w_i) 相同的话,构造 ( ext{kirchhoff}) 矩阵时会在对应的位置加减1,现在就改成在对应位置加上 (1+w_ix)这样一个多项式,然后给矩阵求个行列式,行列式的一次项系数就是包含这条边的生成树个数乘 (w_i) 。所以我们一开给每条边都这样做,然后计算行列式时对 (x^2) 取模即可。
    时间复杂度 (mathcal{O} (n^3sum_{i=1}^{maxw}sigma_0(i)))

    #include<bits/stdc++.h>
    #define rg register
    #define il inline
    #define cn const
    #define gc getchar()
    #define fp(i,a,b) for(rg int i=(a),ed=(b);i<=ed;++i)
    #define fb(i,a,b) for(rg int i=(a),ed=(b);i>=ed;--i)
    #define go(u) for(rg int i=head[u];~i;i=e[i].nxt)
    using namespace std;
    typedef cn int cint;
    typedef long long LL;
    il void rd(int &x){
        x = 0;
    	rg int f(1); rg char c(gc);
    	while(c<'0'||'9'<c){if(c=='-')f=-1;c=gc;}
    	while('0'<=c&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=gc;
    	x*=f;
    }
    cint maxn = 31, maxm = 440, maxw = 152510, mod = 998244353;
    int n, m, mx, ans;
    int pri[maxw], cnt, isnp[maxw], phi[maxw];
    int tot, id[maxm];
    il int fpow(int a, int b, int ans = 1){
    	for(; b; b >>= 1, a = 1ll*a*a%mod)if(b&1)ans = 1ll*ans*a%mod;
    	return ans;
    }
    struct node{int fi, se;}kir[maxn][maxn];
    il node operator + (cn node &x, cn node &y){return (node){(x.fi+y.fi)%mod, (x.se+y.se)%mod};}
    il node operator - (cn node &x, cn node &y){return (node){(x.fi-y.fi+mod)%mod, (x.se-y.se+mod)%mod};}
    il node operator * (cn node &x, cn node &y){return (node){1ll*x.fi*y.fi%mod, (1ll*x.fi*y.se+1ll*x.se*y.fi)%mod};}
    il node operator / (cn node &x, cn node &y){
    	rg int inv = fpow(y.fi, mod-2), sinv = 1ll*inv*inv%mod;
    	return (node){1ll*x.fi*inv%mod, (1ll*x.se*y.fi%mod-1ll*x.fi*y.se%mod+mod)*sinv%mod};
    }
    struct edge{int u, v, w;}e[maxm];
    il void SWAP(node *a, node *b){fp(i, 1, n)swap(a[i], b[i]);}
    il int matrix_tree(){
    	if(tot < n-1)return 0;
    	node ans = (node){1, 0};
    	memset(kir, 0, sizeof kir);
    	fp(i, 1, tot){
    		++kir[e[id[i]].u][e[id[i]].u].fi, ++kir[e[id[i]].v][e[id[i]].v].fi;
    		--kir[e[id[i]].u][e[id[i]].v].fi, --kir[e[id[i]].v][e[id[i]].u].fi;
    		kir[e[id[i]].u][e[id[i]].u].se += e[id[i]].w, kir[e[id[i]].v][e[id[i]].v].se += e[id[i]].w;
    		kir[e[id[i]].u][e[id[i]].v].se -= e[id[i]].w, kir[e[id[i]].v][e[id[i]].u].se -= e[id[i]].w;
    	}
    	fp(i, 1, n)fp(j, 1, n)kir[i][j] = (node){(kir[i][j].fi+mod)%mod, (kir[i][j].se+mod)%mod};
    	fp(i, 2, n){
    		if(!kir[i][i].fi){
    			fp(j, i+1, n)if(kir[j][i].fi){
    				ans = (node){mod-ans.fi, mod-ans.se}, SWAP(kir[i], kir[j]);
    				break;
    			}
    		}
    		rg node mlt;
    		fp(j, i+1, n){
    			mlt = kir[j][i]/kir[i][i];
    			fp(k, i, n)kir[j][k] = kir[j][k]-kir[i][k]*mlt;
    		}
    		ans = ans*kir[i][i];
    	}
    	return ans.se;
    }
    int main(){
    	rd(n), rd(m);
    	fp(i, 1, m)rd(e[i].u), rd(e[i].v), rd(e[i].w), mx = max(mx, e[i].w);
    	phi[1] = 1;
    	fp(i, 2, mx){
    		if(!isnp[i])pri[++cnt] = i, phi[i] = i-1;
    		for(rg int j = 1; j <= cnt && pri[j]*i <= mx; ++j){
    			isnp[i*pri[j]] = 1;
    			if(i%pri[j] == 0){phi[i*pri[j]] = phi[i]*pri[j]; break;}
    			phi[i*pri[j]] = phi[i]*phi[pri[j]];
    		}
    	}
    	fp(i, 1, mx){
    		tot = 0;
    		fp(j, 1, m)if(e[j].w % i == 0)id[++tot] = j;
    		ans = (ans+1ll*phi[i]*matrix_tree())%mod;
    	}
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    算法笔记--中国剩余定理
    算法笔记--辛普森积分公式
    算法笔记--数学之不定方程解的个数
    算法笔记--卢卡斯定理
    洛谷 P3808 【模板】AC自动机(简单版)洛谷 P3796 【模板】AC自动机(加强版)
    hihocoder #1419 : 后缀数组四·重复旋律4
    codevs 3044 矩形面积求并 || hdu 1542
    Stamps ans Envelope Sive UVA
    洛谷 P2061 [USACO07OPEN]城市的地平线City Horizon
    bzoj 3277: 串
  • 原文地址:https://www.cnblogs.com/akura/p/14577657.html
Copyright © 2020-2023  润新知