CodeForces 1408G Clusterization Counting
题意
给定 \(n\) 个点的无向带权完全图,边权为 \(1\sim\frac{n(n-1)}{2}\)。对于满足 \(1\leq k\leq n\) 的每个 \(k\) 求出将原图划分成 \(k\) 个组的方案数,满足组间边的权大于组内边的权值,答案对 \(998244353\) 取模。
\(\texttt{Data Range:}1\leq n\leq 1500\)
题解
这个题蛮好的,只是我赛时没有想出来(甚至差点没有看懂题目),果然还是我太菜了/kk
首先从小到大把边加进来,然后可以发现一个结论:一个连通块是满足条件的当且仅当在加完某条边之后这个连通块是一个团。
这个时候可以直接用类似于 Kruskal 的方法:从小到大加边,并查集维护一下这个连通块的大小和边数,当加完某条边时候可以满足这个连通块是一个团的话就标记一下这个连通块是可以的。
这个时候好像是可以 DP 了,但是复杂度会爆炸。
考虑优化一下,在从小到大加边的过程中考虑 Kruskal 重构树。由于重构树新加的节点维护的是一个连通块,其叶子节点是连通块中所有的节点,所以可以对重构树进行 dfs,用一段区间表示一个连通块。
于是现在变成了有一些区间,要从中选出 \(k\) 个覆盖 \(1\sim n\) 的所有位置。把所有区间挂到右端点上,设 \(f_{i,j}\) 表示当前位置为 \(i\) 并且钦定当前最后一个区间右端点为 \(i\),选出了 \(j\) 个区间的答案,转移的时候枚举一下最后一个区间的左端点是什么就没了。
时间复杂度 \(O(n^2\log n)\),主要瓶颈在排序上。
代码
#include<bits/stdc++.h>
using namespace std;
typedef int ll;
typedef long long int li;
const ll MAXN=3e3+51,MOD=998244353;
struct EdgeForKruskal{
ll from,to,dist;
inline bool operator <(const EdgeForKruskal &rhs)const
{
return this->dist<rhs.dist;
}
};
EdgeForKruskal ed[MAXN*MAXN];
ll n,m,idx,u,v,itvc;
ll x[MAXN][MAXN],f[MAXN][MAXN],ffa[MAXN],sz[MAXN],edc[MAXN];
ll l[MAXN],r[MAXN],flg[MAXN];
vector<ll>g[MAXN],itv[MAXN];
inline ll read()
{
register ll num=0,neg=1;
register char ch=getchar();
while(!isdigit(ch)&&ch!='-')
{
ch=getchar();
}
if(ch=='-')
{
neg=-1;
ch=getchar();
}
while(isdigit(ch))
{
num=(num<<3)+(num<<1)+(ch-'0');
ch=getchar();
}
return num*neg;
}
inline ll find(ll x)
{
return ffa[x]==x?x:ffa[x]=find(ffa[x]);
}
inline void add(ll x)
{
if((++edc[x])==sz[x]*(sz[x]-1)/2)
{
flg[x]=1;
}
}
inline void dfs(ll x)
{
if(x<=n)
{
return (void)(l[x]=r[x]=++itvc);
}
l[x]=n+1;
for(register int to:g[x])
{
dfs(to),l[x]=min(l[x],l[to]);
}
r[x]=itvc,flg[x]?itv[r[x]].push_back(l[x]):(void)1;
}
int main()
{
n=read(),f[0][0]=1;
for(register int i=1;i<=n;i++)
{
for(register int j=1;j<=n;j++)
{
x[i][j]=read();
j>i?(void)(ed[++m]=(EdgeForKruskal){i,j,x[i][j]}):(void)1;
}
}
idx=n,sort(ed+1,ed+m+1);
for(register int i=1;i<=n;i++)
{
flg[i]=1,itv[i].push_back(i),ffa[i]=i,sz[i]=1,edc[i]=0;
}
for(register int i=1;i<=m;i++)
{
u=find(ed[i].from),v=find(ed[i].to);
if(u==v)
{
add(u);
}
else
{
g[++idx].push_back(u),g[idx].push_back(v);
ffa[u]=ffa[v]=ffa[idx]=idx;
sz[idx]=sz[u]+sz[v],edc[idx]=edc[u]+edc[v],add(idx);
}
}
dfs(idx);
for(register int i=1;i<=n;i++)
{
for(register int j=1;j<=n;j++)
{
for(register int k:itv[i])
{
f[i][j]=(f[i][j]+f[k-1][j-1])%MOD;
}
}
}
for(register int i=1;i<=n;i++)
{
printf("%d ",f[n][i]);
}
}
CodeForces 1408G Clusterization Counting的更多相关文章
- Codeforces 954H Path Counting 【DP计数】*
Codeforces 954H Path Counting LINK 题目大意:给你一棵n层的树,第i层的每个节点有a[i]个儿子节点,然后问你树上的简单路径中长度在1~n*2-2之间的每个有多少条 ...
- Codeforces 372 B. Counting Rectangles is Fun
$ >Codeforces \space 372 B. Counting Rectangles is Fun<$ 题目大意 : 给出一个 \(n \times m\) 的 \(01\) ...
- 【codeforces 335E】 Counting Skyscrapers
http://codeforces.com/problemset/problem/335/E (题目链接) 题意 懒得写了= = Solution 这题咋不上天= =. 参考题解:http://blo ...
- Codeforces 911D. Inversion Counting (数学、思维)
题目链接:Inversion Counting 题意: 定义数列{ai|i=1,2,...,n}的逆序对如下:对于所有的1≤j<i≤n,若ai<aj,则<i,j>为一个逆序对. ...
- Codeforces 954H Path Counting(DP)
题目链接 Path Counting 题意 给定一棵高度为$n$的树,给出每一层的每个点的儿子个数(某一层的所有点儿子个数相同). 令$f_{k}$为长度为$k$的路径条数,求$f_{1}, ...
- CodeForces - 990G GCD Counting
Discription You are given a tree consisting of nn vertices. A number is written on each vertex; the ...
- 【Codeforces 372A】Counting Kangaroos is Fun
[链接] 我是链接,点我呀:) [题意] 如果a[i]*2<=a[j]那么i袋鼠可以装进j袋鼠里面 每只袋鼠都只能装一只袋鼠 [题解] 假设最后的方案是(ai,bi) 这里(ai,bi)表示下标 ...
- CodeForces 372 A. Counting Kangaroos is Fun
题意,有n只袋鼠,没每只袋鼠有个袋子,大小为si,一个袋鼠可以进入另外一个袋鼠的袋子里面,当且仅当另一个袋鼠的袋子是他的二倍或二倍一上,然后中国袋鼠就是不可见的,不能出现多个袋鼠嵌套的情况.让你求最少 ...
- CF1408G Clusterization Counting
首先,我们需要给一个连通块找到一个直观的合法判定解. 那么我们必须以一种直观的方式将边按照权值分开,这样才能直观地判定一个合法的组. 一个常见的方式是将边从小到大依次加入进来,那么在任意时刻图上存在的 ...
随机推荐
- 交互平台 - Processing - 开发模板(仿Openframeworks)
之前在CSDN上发表过: https://blog.csdn.net/fddxsyf123/article/details/62425251
- 【小白学PyTorch】16 TF2读取图片的方法
[新闻]:机器学习炼丹术的粉丝的人工智能交流群已经建立,目前有目标检测.医学图像.NLP等多个学术交流分群和水群唠嗑的总群,欢迎大家加炼丹兄为好友,加入炼丹协会.微信:cyx645016617. 参考 ...
- Leetcode-递归&分治
50. Pow(x, n) https://leetcode-cn.com/problems/powx-n/ 实现 pow(x, n) ,即计算 x 的 n 次幂函数. 说明: -100.0 < ...
- [论文理解] Good Semi-supervised Learning That Requires a Bad GAN
Good Semi-supervised Learning That Requires a Bad GAN 恢复博客更新,最近没那么忙了,记录一下学习. Intro 本文是一篇稍微偏理论的半监督学习的 ...
- JavaScript 将十进制数转换成格式类似于 0x000100 或 #000100 的十六进制数
将十进制数转换成格式类似于 0x000100 或 #000100 的十六进制数 1 <!DOCTYPE html> 2 <html> 3 <head> 4 < ...
- Golang搭建接口测试框架
测试报告 使用goconvey作为测试报告,使用方法: 安装 $ go get github.com/smartystreets/goconvey $ $GOPATH/bin/goconvey 导入包 ...
- IDEA中创建父子工程与maven打包Springboot聚合工程报错程序包不存在问题处理
公司新项目需使用java技术栈,便使用IDEA搭建了一个多SpringBoot项目的聚合工程,因为初次使用,遇到了很多问题,maven打包时各种报错,在网上查了好多终于解决了,为巩固记忆,特作此记录. ...
- STM32之旅3——时钟数
STM32之旅3--时钟数 STM32F1是M3内核,它的时钟数很庞大,让一个初学者去看,估计会很吃力,和我们入门的8051单片机的时钟不同,这里又倍频.又分频,而且还分成好多个时钟,不同的外设时钟不 ...
- 联赛模拟测试14 A. 虎
题目描述 这题太虎了,所以没有背景. 给你一棵树,边有黑白两种颜色,你每次可以选择两个点,把这两个点之间的唯一简单路径上的所有边颜色取反,某些边要求最终颜色必须是黑色,还有些边没有要求,问最少操作多少 ...
- 收集的照片信息都是Excel超链接?批量命名很困难?来试试这个自制的下载器吧!
项目背景 作为大学的一名班委,经常要制作各种表格.统计各种信息,成为一名合格的"表哥"是一门必修课.其实Excel的文字信息和数字信息的统计和处理还并不算难题,很多信息可以通过问卷 ...