首页 > 其他分享 >CF920E Connected Components? 题解

CF920E Connected Components? 题解

时间:2023-05-08 18:23:03浏览次数:47  
标签:int 题解 top CF920E st 600010 Connected low now

一道线段树优化建图好题(大雾

扣掉一些边看起来不好做,我们直接大力加上存在的边,然后跑连通块。对于一个点,如果他被扣掉了 \(k\) 个邻居,那么没扣掉的那些形成了至多 \(k+1\) 个连续段,可以用线段树优化建图向每个连续段各用 \(\log\) 的代价连边。

由于总共扣掉了 \(m\) 条边,所以总共连边的次数是 \(O(m)\) 的,建图复杂度为 \(m\log m\),产生 \(O(n+m)\) 个点、\(O(n+m)\) 条边的有向图。

注意到线段树优化建图建的是有向图,如果直接建无向图就会让所有点都在一个连通块。所以按照有向的线段树优化建图做法,如下:

(图为 2 向 3,4 连边)(由于是点向区间连边,只需要一棵线段树即可)

注意到,在 \(2\) 向 \(3,4\) 连边时,\(3,4\) 也会向 \(2\) 连边,故连通块一定形成强连通分量,也不会产生直接连无向图的问题。于是最后对新图跑一下强连通分量即可。

#include <bits/stdc++.h>
using namespace std;
vector<int> a[200010], e[600010];
int n, m, tot, rt;
struct node{int lson, rson;} t[600010];
#define mid (l + r) / 2
void build(int &now, int l = 1, int r = n) {
	if (l == r) {now = l + n; return;}
	now = ++tot;
	build(t[now].lson, l, mid), build(t[now].rson, mid + 1, r);
	e[now].push_back(t[now].lson), e[now].push_back(t[now].rson);
}
void add(int now, int ql, int qr, int x, int l = 1, int r = n) {
	if (ql <= l && qr >= r) {e[x].push_back(now); return;}
	if (ql <= mid) add(t[now].lson, ql, qr, x, l, mid);
	if (qr > mid) add(t[now].rson, ql, qr, x, mid + 1, r);
}
int dfn[600010], low[600010], cnt;
int st[600010], top, col[600010], colcnt, sz[600010];
bool in[600010];
void dfs(int now) {
	low[now] = dfn[now] = ++cnt;
	st[++top] = now, in[now] = 1;
	for (int v : e[now]) {
		if (!dfn[v]) dfs(v), low[now] = min(low[now], low[v]);
		else if (in[v]) low[now] = min(low[now], dfn[v]);
	}
	if (low[now] == dfn[now]) {
		colcnt++;
		while (st[top] != now)
			col[st[top]] = colcnt, in[st[top]] = 0, top--;
		col[st[top]] = colcnt, in[st[top]] = 0, top--;
	}
}
signed main() {
	scanf("%d%d", &n, &m), tot = n * 2;
	for (int i = 1; i <= m; i++) {
		int x, y;
		scanf("%d%d", &x, &y);
		a[x].push_back(y), a[y].push_back(x);
	}
	for (int i = 1; i <= n; i++)
		e[i + n].push_back(i);
	build(rt, 1, n);
	for (int i = 1; i <= n; i++) {
		a[i].push_back(0), a[i].push_back(n + 1);
		sort(a[i].begin(), a[i].end());
		for (int j = 1; j < a[i].size(); j++) {
			if (a[i][j - 1] + 1 == a[i][j]) continue;
			add(rt, a[i][j - 1] + 1, a[i][j] - 1, i);
		}
	}
	for (int i = 1; i <= tot; i++)
		if (!dfn[i]) dfs(i);
	for (int i = 1; i <= n; i++)
		sz[col[i]]++;
	sort(sz + 1, sz + colcnt + 1);
	vector<int> ans;
	for (int i = 1; i <= colcnt; i++)
		if (sz[i]) ans.push_back(sz[i]);
	printf("%d\n", (int)ans.size());
	for (int x : ans) printf("%d ", x);
	puts("");
	return 0;
}

标签:int,题解,top,CF920E,st,600010,Connected,low,now
From: https://www.cnblogs.com/cxm1024/p/17382755.html

相关文章

  • 装最多水的容器 - 题解
    1.问题描述  原题的地址见:ContainerWithMostWater-LeetCode.此问题等价于如下问题:    给定所有元素非负的数组[a0,a1,...,an-1],计算(j-i)|aj-ai|(其中j>i)的最小值。 2.暴力解法  有了问题的描述,很容易写出暴力求解的算法:intmaxArea(vector<int>......
  • Windows 安装 pycrypto 常见问题解决
    关于python使用Crypto.Cipher模块,ImportError:Nomodulenamed'Crypto' 常见问题解决1. 需要安装:MicrosoftVisualC++14.0error:MicrosoftVisualC++14.0isrequired.Getitwith"MicrosoftVisualC++BuildTools":http://landinghub.visualstudio.co......
  • CF1794D 题解
    一、题目描述:一个正整数$m$可以被唯一分解成$p_1^{e_1}\timesp_2^{e_2}\times...\timesp_k^{e_k}$的形式,其中$p_1,p_2,...,p_k$为互不相同的质数,$e_1,e_2,...,e_k$为正整数。定义一个可重集$f(m)$为$\{p_1,e_1,p_2,e_2,...,p_k,e_k\}$。现在给定正整数$......
  • 51nod 1365 Fib(N) mod Fib(K)-题解
    51nod1365Fib(N)modFib(K)个人评价:考一些奇奇怪怪的知识点呢算法矩阵快速幂、斐波那契公式题面求\(F_n\%F_k\)的值,\(1\leqn,k\leq1e18\)问题分析我一开始居然想着直接矩阵快速幂求出两个值算,我也是真的牛……我们要知道这些斐波那契公式(考的真怪)\[F_{-n}=(-1)^{n......
  • 2023ccpc湖北省赛/2023 Hubei Provincial Collegiate Programming Contest个人题解
    2023HubeiProvincialCollegiateProgrammingContestAPrimeMagicWalkAlonehasasequence\(a_1,a_2,...,a_n\),andhecanuseamagiconit:Chooseanoddprimenumber\(p\)andaninterval\([l,r]⊆[1,n]\)satisfying\(r−l+1=p\),andthenadd......
  • MultiDex使用方法及由此导致的crash、ANR问题解决方案
    Android开发的朋友,如果是在开发一款中大型应用时,都会碰到这么一个问题,就是dex分拆问题,google给出的解决方案MultiDex。现象:有些APP本身功能比较多,再加上一些其它三方的SDK,慢慢的发现dex越来越大,直到有一天编译出现如下错误:Error:Thenumberofmethodreferencesina.dexfile......
  • 十二代酷睿处理器N100 N200 N305 等安装ESXI紫屏问题解决办法
    12代大小核紫屏报错解决方案四部曲1、安装界面倒计时结束之前,按SHIFT+O,在原有命令后面加空格后输入以下代码cpuUniformityHardCheckPanic=FALSE2、安装完ESXI之后会重启,在重启界面倒计时结束前,再操作一次,按住SHIFT+O,输入cpuUniformityHardCheckPanic=FALSE3、进入ESXI把SSH功能......
  • 力扣《环形链表Ⅱ》超详细题解
    作为经典题目的《环形链表Ⅱ》,我认为这题还是有专门出一期博客的分量的,大家也可以自己事先按照自己的理解写一写,然后再来看题解,毕竟自己悟出来的东西是比吸收别人的来的更深刻。一、题目给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。......
  • CF1829B 题解
    题目思路先定义变量\(t,ans\)。循环从\(0\)到\(n-1\),对于第\(i\)个数,如果为\(0\),\(t=t+1\),否则将\(t\)清零。每次循环\(ans=\max(ans,t)\)表示最多有多少个连续的\(0\)。最后输出\(ans\)即可。核心代码点击查看代码voidsolve(){intn=read(),a[1005],a......
  • AtCoder Regular Contest 159简要题解
    AtCoderRegularContest159传送门A-CopyandPasteGraph图的邻接矩阵为\[\left(\begin{matrix}A&A&\cdots&A\\A&A&\cdots&A\\\cdots&\cdots&\cdots&\cdots\\A&A&\cdots&A\e......