线段树 C - Connected Components? CodeForces - 920E
这个题目居然可以用线段树写,好震惊,如果不是在线段树专题肯定想不到,但是就算在线段树的专题里面,我也不太会怎么写。
这个题目大意是,给你n m n代表n个点,m代表m条边,然后就是m行,每行两个数字,一个u一个v。
这个意思是u和v不想连,然后问你这个n个点形成了多少个联通块。
思路大概是这样,首先随意枚举一个点,然后直接更新每一个点的值+1,先消除自己的影响,然后对于每一个和它连的点的值都-1
然后查找一个值大于0 的点,再继续循环这个过程,如果找不到了就推出这个循环。
这个复杂度我不太会算。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <map>
#include <string>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 4e5 + 10;
int cnt[maxn * 4], maxs[maxn * 4];
int lazy[maxn * 4]; void push_up(int id)
{
if (maxs[id << 1] < maxs[id << 1 | 1]) {
maxs[id] = maxs[id << 1 | 1];
cnt[id] = cnt[id << 1 | 1];
}
else {
maxs[id] = maxs[id << 1];
cnt[id] = cnt[id << 1];
}
// printf("cnt[%d]=%d cnt[%d]=%d\n", id << 1, cnt[id << 1], id << 1 | 1, cnt[id << 1 | 1]);
// printf("cnt[%d]=%d\n", id, cnt[id]);
} void build(int id,int l,int r)
{
lazy[id] = 0;
if(l==r)
{
cnt[id] = l;
maxs[id] = 0;
return;
}
int mid = (l + r) >> 1;
build(id << 1, l, mid);
build(id << 1 | 1, mid + 1, r);
push_up(id);
} void push_down(int id)
{
//printf("id=%d\n", id);
if (lazy[id] == 0) return;
maxs[id << 1] += lazy[id];
maxs[id << 1 | 1] += lazy[id];
lazy[id << 1] += lazy[id];
lazy[id << 1 | 1] += lazy[id];
lazy[id] = 0;
} void update(int id,int l,int r,const int x,const int y,int val)
{
// printf("id=%d l=%d r=%d x=%d y=%d\n", id, l, r, x, y);
if(x<=l&&y>=r)
{
maxs[id] += val;
lazy[id] += val;
return;
}
push_down(id);
int mid = (l + r) >> 1;
if (x <= mid) update(id << 1, l, mid, x, y, val);
if (y > mid) update(id << 1 | 1, mid + 1, r, x, y, val);
push_up(id);
} struct node
{
int v, nxt;
node(int v=0,int nxt=0):v(v),nxt(nxt){}
}ex[maxn];
int head[maxn], tot = 0, num;
void init()
{
memset(head, -1, sizeof(head));
tot = 0, num = 0;
} void add(int u,int v)
{
ex[tot] = node(v, head[u]);
head[u] = tot++;
ex[tot] = node(u, head[v]);
head[v] = tot++;
}
int a[maxn];
bool vis[maxn];
int n, m; int dfs(int x)
{
int res = 0;
build(1, 1, n);
while(1)
{
vis[x] = 1;
res++;
update(1, 1, n, 1, n, 1);
update(1, 1, n, x, x, -inf);
for (int i = head[x]; i != -1; i = ex[i].nxt)
{
int v = ex[i].v;
update(1, 1, n, v, v, -1);
}
// printf("\n\n");
if (maxs[1] <= 0) break;
x = cnt[1];
}
return res;
} int main()
{
init();
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
int u, v;
scanf("%d%d", &u, &v);
add(u, v);
}
for(int i=1;i<=n;i++)
{
if (vis[i]) continue;
a[num++] = dfs(i);
}
sort(a, a + num);
printf("%d\n", num);
for (int i = 0; i < num; i++) printf("%d ", a[i]);
return 0;
}
线段树 C - Connected Components? CodeForces - 920E的更多相关文章
- Connected Components? Codeforces - 920E || 洛谷 P3452 &&bzoj1098 [POI2007]BIU-Offices
https://codeforces.com/contest/920/problem/E https://www.luogu.org/problemnew/show/P3452 https://www ...
- Connected Components? CodeForces - 920E (bfs)
大意:给定无向图, 求补图的连通块数 bfs模拟即可, 这里用了map存图, set维护未划分的点集, 复杂度$O(nlog^2n)$, 用链表的话可以$O(n)$ #include <iost ...
- 线段树+矩阵快速幂 Codeforces Round #373 (Div. 2) E
http://codeforces.com/contest/719/problem/E 题目大意:给你一串数组a,a[i]表示第i个斐波那契数列,有如下操作 ①对[l,r]区间+一个val ②求出[l ...
- 数据结构(线段树):Educational Codeforces Round 6 620E. New Year Tree
E. New Year Tree time limit per test 3 seconds memory limit per test 256 megabytes input standard in ...
- codeforces 1217E E. Sum Queries? (线段树
codeforces 1217E E. Sum Queries? (线段树 传送门:https://codeforces.com/contest/1217/problem/E 题意: n个数,m次询问 ...
- 线段树详解 (原理,实现与应用)(转载自:http://blog.csdn.net/zearot/article/details/48299459)
原文地址:http://blog.csdn.net/zearot/article/details/48299459(如有侵权,请联系博主,立即删除.) 线段树详解 By 岩之痕 目录: 一:综述 ...
- Codeforces 1270H - Number of Components(线段树)
Codeforces 题目传送门 & 洛谷题目传送门 首先需发现一个性质,那就是每一个连通块所对应的是一个区间.换句话说 \(\forall l<r\),若 \(l,r\) 在同一连通块 ...
- Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)
题目链接:http://codeforces.com/contest/522/problem/D 题目大意: 给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...
- Educational Codeforces Round 6 E. New Year Tree dfs+线段树
题目链接:http://codeforces.com/contest/620/problem/E E. New Year Tree time limit per test 3 seconds memo ...
随机推荐
- 【Java】抽象类、接口
什么是抽象类? 特点: - 抽象类几乎普通类一样,除了不能实例化 - 不能实例化不代表没有构造器,依然可以声明构造器,便于子类实例化调用 - 具有抽象方法的类,一定是抽象类 abstract 抽象的 ...
- c++学习day01基础知识学习
一.代码示例解析: #include <iostream> int main() { using namespace std; cout << "come up an ...
- GeoGebra简单使用
上课过程中的一些知识和一丢丢工具使用例子 1.常用的变量输入 2.好用的函数检视工具 3.使用动态的移动,关键是右键-开启跟踪 4.输入指令(推荐用英文输入,因为有提示)
- python基础:如何使用python pandas将DataFrame转换为dict
之前在知乎上看到有网友提问,如何将DataFrame转换为dict,专门研究了一下,pandas在0.21.0版本中是提供了这个方法的.下面一起学习一下,通过调用help方法,该方法只需传入一个参数, ...
- Windows线程+进程通信
一 Windows线程进程 1)定义 按照MS的定义, Windows中的进程简单地说就是一个内存中的可执行程序, 提供程序运行的各种资源. 进程拥有虚拟的地址空间, 可执行代码, 数据, 对象句柄集 ...
- 二进制部署kubernetes集群_kube-apiserver提示"watch chan error: etcdserver: mvcc: required revision has been compacted'
查看kube-apiserver状态 [root@yxz-cluster01 ~]# systemctl status kube-apiserver -l ● kube-apiserver.servi ...
- python os模块判断文件是否存在
import os os.path.exists(test_file.txt)
- Liunx常用操作(二)-vim中删除命令
VIM简介 Vim是一个类似于Vi的著名的功能强大.高度可定制的文本编辑器,在Vi的基础上改进和增加了很多特性.VIM是自由软件.Vim普遍被推崇为类Vi编辑器中最好的一个,事实上真正的劲敌来自Ema ...
- 算法笔记刷题4(PAT B1009)
这一题本来不应该有什么问题的,我很快写出来了,在dev c++里面运行也正常.但是放到pat以后出现了问题.更换了c/c++都不行通过编译. #include <cstdio> #incl ...
- python爬虫-User-Agent的伪造
某些网站会识别python爬虫程序并阻断,通过构造User_Agent可以抵抗某些反爬虫机制 用fake-useragent这个库就能很好的实现 pycharm中安装步骤 产生随机的User-Agen ...