https://codeforces.com/gym/102012
A.Rikka with Minimum Spanning Trees(求最小生成树个数与总权值的乘积)
#include<bits/stdc++.h> using namespace std; typedef unsigned long long ull; const int maxn=100010; const ull mod=1e9+7; int m,n,f[maxn]; ull k1,k2; struct edge { int u,v; ull w; } e[maxn]; int find(int x) { return x==f[x]?x:f[x]=find(f[x]); } bool cmp(edge a,edge b) { if (a.w!=b.w) return a.w<b.w; if (a.u!=b.u) return a.u<b.u; if (a.v!=b.v) return a.v<b.v; } ull xorShift128Plus() { ull k3=k1,k4=k2; k1=k4; k3^=k3<<23; k2=k3^k4^(k3>>17)^(k4>>26); return k2+k4; } void gen() { scanf("%d%d%llu%llu",&n,&m,&k1,&k2); for (int i=1; i<=n; i++) { f[i]=i; } for (int i=1; i<=m; i++) { e[i].u=xorShift128Plus()%n+1; e[i].v=xorShift128Plus()%n+1; e[i].w=xorShift128Plus(); if (e[i].u>e[i].v) { swap(e[i].u,e[i].v); } } } void kurskal() { gen(); sort(e+1,e+1+m,cmp); int cnt=0; ull cost=0,time=1,res; for (int i=1; i<=m; i++) { int fu=find(e[i].u),fv=find(e[i].v); if (fu!=fv) { res=1; f[fu]=fv; cost=(cost+e[i].w)%mod; cnt++; while (i+1<=m&&e[i].u==e[i+1].u&&e[i].v==e[i+1].v&&e[i].w==e[i+1].w) { i++; res++; } time=time*res%mod; } if (cnt==n-1) { break; } } if (cnt==n-1) { printf("%llu ",cost%mod*time%mod); } else { printf("0 "); } } int main() { int _; scanf("%d",&_); while (_--) { kurskal(); } return 0; }