首页 > 其他分享 >题解 CF1857G【Counting Graphs】

题解 CF1857G【Counting Graphs】

时间:2023-08-09 18:26:48浏览次数:34  
标签:return 题解 ll dsu CF1857G 权值 ans Counting find

一个非常显然的事情是:总方案数即为每条边方案数之积。

树边已经确定,考察每条非树边 \((u,v)\) 可以怎么取。给定的树 \(T\) 是唯一最小生成树,这意味着非树边 \((u,v)\) 要么不存在,要么权值大于 \(T\) 上 \((u,v)\) 之间任意一条边的权值。设 \(T\) 上 \((u,v)\) 间的最大边权为 \(k\),则 \((u,v)\) 对答案的贡献为 \(S-k+1\)。

但我们无法枚举每条非树边计算贡献,因为复杂度为 \(O(n^2)\)。考虑将“一类”非树边放到一起计算。

考虑 Kruskal 算法的过程,每次取出权值最小的边 \((u,v,w)\) 加入最小生成树,并将两个连通块 \(B_1,B_2\) 合并。当一条边 \((u,v,w)\) 加入最小生成树时,它就是跨越两个连通块 \(B_1,B_2\) 的任意一对点间的最大权值。这就意味着对于每一对 \(B_1\times B_2\) 中的点对(\(\times\) 是集合直积,\((u,v)\) 除外),这条边要么不存在,要么权值大于 \(w\)。

我们用桶统计出对于每个 \(w\),有多少条边的要求是“要么不存在,要么权值大于 \(w\)”,并用快速幂计算即可。

时间复杂度 \(O(n\log n+n\log S)\)。

// Problem: G. Counting Graphs
// Contest: Codeforces - Codeforces Round 891 (Div. 3)
// URL: https://codeforces.com/contest/1857/problem/G
// Memory Limit: 256 MB
// Time Limit: 2000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

//By: OIer rui_er
#include <bits/stdc++.h>
#define rep(x,y,z) for(ll x=(y);x<=(z);x++)
#define per(x,y,z) for(ll x=(y);x>=(z);x--)
#define debug(format...) fprintf(stderr, format)
#define fileIO(s) do{freopen(s".in","r",stdin);freopen(s".out","w",stdout);}while(false)
using namespace std;
typedef long long ll;

mt19937 rnd(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
ll randint(ll L, ll R) {
    uniform_int_distribution<ll> dist(L, R);
    return dist(rnd);
}

template<typename T> void chkmin(T& x, T y) {if(x > y) x = y;}
template<typename T> void chkmax(T& x, T y) {if(x < y) x = y;}

const ll N = 2e5+5, mod = 998244353;

ll T, n, S;

struct Edge {
    ll u, v, w;
}e[N];

struct Dsu {
    ll fa[N], sz[N];
    void init(ll x) {rep(i, 1, x) fa[i] = i, sz[i] = 1;}
    ll find(ll x) {return x == fa[x] ? x : fa[x] = find(fa[x]);}
    bool same(ll x, ll y) {return find(x) == find(y);}
    bool merge(ll x, ll y) {
        if(same(x, y)) return false;
        x = find(x); y = find(y);
        fa[x] = y;
        sz[y] += sz[x];
        return true;
    }
}dsu;

map<ll, ll> cnt;

ll qpow(ll x, ll y) {
    ll ans = 1;
    for(; y; y >>= 1, x = x * x % mod) if(y & 1) ans = ans * x % mod;
    return ans;
}

int main() {
    for(scanf("%lld", &T); T; T--) {
        map<ll, ll>().swap(cnt);
        scanf("%lld%lld", &n, &S);
        rep(i, 1, n-1) scanf("%lld%lld%lld", &e[i].u, &e[i].v, &e[i].w);
        sort(e+1, e+n, [](const Edge& a, const Edge& b) {return a.w < b.w;});
        dsu.init(n);
        rep(i, 1, n-1) {
            ll u = e[i].u, v = e[i].v, w = e[i].w;
            cnt[w] += dsu.sz[dsu.find(u)] * dsu.sz[dsu.find(v)] - 1;
            dsu.merge(u, v);
        }
        ll ans = 1;
        for(auto [key, val] : cnt) if(val) ans = ans * qpow(S-key+1, val) % mod;
        printf("%lld\n", ans);
    }
    return 0;
}

标签:return,题解,ll,dsu,CF1857G,权值,ans,Counting,find
From: https://www.cnblogs.com/ruierqwq/p/CF-1857G.html

相关文章

  • 杭电多校 2023 杂题题解
    打算只写点有意思的题。D1JEasyproblemI注意到\(x_i\)单增,所以一个数被减到负数之后,所有的操作都会将它减到负数,也就等价于乘\(-1\)再相加。使用一棵线段树维护所有数,将这些数分为两种,一种如上,一种是区间减。最终所有数都会变为需要乘\(-1\)再相加的数,于是只要每次精......
  • luogu P4200 千山鸟飞绝 题解 【一维数组套平衡树】
    目录题目解题思路code题目题目链接解题思路首先,此题有明显的插入、删除、查找,所以必须要使用平衡树。考虑如何使用平衡树维护每个鸟的状态。发现很不方便,因为鸟的位置改变,整个平衡树的值都要修改。考虑针对每个节点开一颗平衡树,这样就有\(3e4\times3e4\)棵树。这显然太多了......
  • P9507 [BalkanOI2018] Popa 题解
    原题传送门题目描述Ghiță有一个下标从\(0\)开始的正整数序列\(S\)。因为他是喀尔巴阡的国王,所以他想要构造一个节点编号为\(0,1,\ldots,N-1\)的二叉树,满足:树的中序遍历按节点编号升序排列。二叉树的中序遍历由以根的左子节点(如果存在)为根形成的子树的中序遍历,根的节......
  • 桐柏邀请赛 S15 题解
    定位:给中低段位一点压力,给中高段位一点信心!A发现只是单向变换\((0\to1)\),用两个变量维护位置最小值和最大值即可。#defineintlonglongintn,q,maxn,minn=1e18+1,x;signedmain(){ n=read(),q=read(); while(q--){ x=read(); maxn=max(maxn,x); minn=min(minn,x......
  • CF1857B Maximum Rounding 题解
    题面题目大意给定\(T\)组数据,每组数据一个自然数\(n\),可以多次选择第\(k\)位数进行四舍五入,求出四舍五入后该数的最大值。分析思路思想:贪心。这里给定了两种操作。四舍和五入。显然我们想要让最终的结果最大,我们的操作只能进行五入而不可以进行四舍。因为如果我们进行了......
  • 国标GB28181视频平台LntonGBS(源码版)国标平台级联时,通道上传上级宇视平台无法接收的问
    LntonGBS是基于公安部推出的GB/T28181协议开发的视频平台,在安防监控领域应用广泛。下面是一些关于LntonGBS平台的主要特点:GB/T28181协议兼容性、视频直播和转码、云端录像和存储、语音对讲和警告功能、平台级联功能。通过以上的功能和特点,LntonGBS平台能够满足安防监控领域各类场景......
  • sudo: a terminal is required to read the password; either use..... 问题解决方法
    转载自:sudo:aterminalisrequiredtoreadthepassword;eitheruse……问题解决方法_akaiziyou的博客-CSDN博客问题sudo:aterminalisrequiredtoreadthepassword;eitherusethe-Soptiontoreadfromstandardinorconfigureanaskpasshelper出现场景某个......
  • Codeforces Round 891 (Div. 3) 题解
    A.ArrayColoring因为:偶数+偶数=偶数奇数+奇数=偶数奇数+偶数=奇数所以设\(s1\)为奇数之和,\(s2\)为偶数之和\(s2\)必定是偶数如果奇数的个数为偶数,则\(s1\)为偶数;否则是奇数而在\(s1\)为奇数时,即使拿一个奇数加到\(s2\)里,那么也是不合法的所以直接判断奇数的......
  • CF1477E题解
    洛谷博客链接此篇未投洛谷题解,因为写得太菜了qwq。CF1477E&大户爱的送分题题解(CF1477E为我出的校内模拟赛的一道题——《大户爱的送分题》的待修版本)大户爱的送分题文件名OhtoAiFirst.cpp/.in/.out,时间限制\(1\)秒,空间限制\(256MB\)。注意第一个字母是O而不是0。题目背......
  • CF1030F题解
    CF1030F题解传送门 更好的阅读体验简化题意:有$n$个小球,每个小球在位置$a_i$,移动一格的代价是$w_i$,有两种操作,一种是将$w_x$改成$y$,一种是查询$\min\limits_{x=1}^n\{\sum\limits_{i=l}^rw_i\times(|a_x-a_i|+|x-i|)\}$。思路很好的线段树二分练手题。对于每......