题目传送门

题意:训练指南P248

分析:第一个操作可以用并查集实现,保存某集合的最小高度和最大高度以及城市个数。运用线段树成端更新来统计一个区间高度的个数,此时高度需要离散化。这题两种数据结构一起使用,联系紧密。

#include <bits/stdc++.h>
using namespace std; const int N = 1e5 + 5;
const int M = 3 * N;
const int INF = 0x3f3f3f3f;
struct Point {
int x, y;
Point() {}
Point(int x, int y) : x (x), y (y) {}
};
struct Query {
int op;
int u, v, w;
}q[2*N]; #define lson l, mid, o << 1
#define rson mid + 1, r, o << 1 | 1
int city[M<<2], num[M<<2], col[M<<2], col2[M<<2]; //Segment_Tree
void push_down(int o) {
if (col[o]) {
col[o<<1] += col[o]; col[o<<1|1] += col[o];
city[o<<1] += col[o]; city[o<<1|1] += col[o];
col[o] = 0;
}
if (col2[o]) {
col2[o<<1] += col2[o]; col2[o<<1|1] += col2[o];
num[o<<1] += col2[o]; num[o<<1|1] += col2[o];
col2[o] = 0;
}
}
void build(int l, int r, int o) {
col[o] = 0; col2[o] = 0;
if (l == r) {
city[o] = num[o] = 0;
return ;
}
int mid = l + r >> 1;
build (lson); build (rson);
}
void updata(int ql, int qr, int c1, int c2, int l, int r, int o) {
if (ql <= l && r <= qr) {
col[o] += c1; col2[o] += c2;
city[o] += c1; num[o] += c2;
return ;
}
push_down (o);
int mid = l + r >> 1;
if (ql <= mid) updata (ql, qr, c1, c2, lson);
if (qr > mid) updata (ql, qr, c1, c2, rson);
}
void query(int p, int l, int r, int o) {
if (l == r && l == p) {
printf ("%d %d\n", city[o], num[o]); return ;
}
push_down (o);
int mid = l + r >> 1;
if (p <= mid) query (p, lson);
else query (p, rson);
} int n, m, bound; int rt[N], rk[N], maxy[N], miny[N]; //DSU
void init(void) {
memset (rt, -1, sizeof (rt));
memset (rk, 0, sizeof (rk));
}
int Find(int x) {
return rt[x] == -1 ? x : rt[x] = Find (rt[x]);
}
void Union(int u, int v) {
u = Find (u); v = Find (v);
if (u == v) return ;
if (rk[u] > rk[v]) swap (u, v);
if (rk[u]) updata (miny[u], maxy[u], -1, -(rk[u] + 1), 1, bound, 1);
if (rk[v]) updata (miny[v], maxy[v], -1, -(rk[v] + 1), 1, bound, 1); maxy[v] = max (maxy[v], maxy[u]);
miny[v] = min (miny[v], miny[u]); rt[u] = v; rk[v] += rk[u] + 1;
rk[u] = 0;
updata (miny[v], maxy[v], 1, rk[v] + 1, 1, bound, 1);
} Point point[N];
vector<int> ys; void run(void) {
init (); build (1, bound, 1);
for (int i=1; i<=n; ++i) {
miny[i] = maxy[i] = point[i].y;
}
for (int i=1; i<=m; ++i) {
if (q[i].op == 0) {
Union (q[i].u, q[i].v);
}
else {
query (q[i].w, 1, bound, 1);
}
}
} int main(void) {
int T; scanf ("%d", &T);
while (T--) {
scanf ("%d", &n);
int x, y;
ys.clear ();
for (int i=1; i<=n; ++i) {
scanf ("%d%d", &x, &y); point[i] = Point (x, 2 * y);
ys.push_back (point[i].y);
}
char str[10];
int u, v; double t;
scanf ("%d", &m);
for (int i=1; i<=m; ++i) {
scanf ("%s", &str);
if (str[0] == 'r') {
scanf ("%d%d", &u, &v);
q[i].op = 0; q[i].u = u + 1, q[i].v = v + 1;
}
else if (str[0] == 'l') {
scanf ("%lf", &t);
q[i].op = 1; q[i].w = (int) (2 * t);
ys.push_back (q[i].w);
}
}
sort (ys.begin (), ys.end ());
ys.erase (unique (ys.begin (), ys.end ()), ys.end ());
bound = 200010;
for (int i=1; i<=n; ++i) {
point[i].y = lower_bound (ys.begin (), ys.end (), point[i].y) - ys.begin () + 1;
}
for (int i=1; i<=m; ++i) {
if (q[i].op == 1) {
q[i].w = lower_bound (ys.begin (), ys.end (), q[i].w) - ys.begin () + 1;
}
}
run ();
} return 0;
}

  

并查集 + 线段树 LA 4730 Kingdom的更多相关文章

  1. UVA1455 - Kingdom(并查集 + 线段树)

    UVA1455 - Kingdom(并查集 + 线段树) 题目链接 题目大意:一个平面内,给你n个整数点,两种类型的操作:road x y 把city x 和city y连接起来,line fnum ...

  2. 并查集&线段树&树状数组&排序二叉树

    超级无敌巨牛逼并查集(带权并查集)https://vjudge.net/problem/UVALive-4487 带删点的加权并查集 https://vjudge.net/problem/UVA-11 ...

  3. 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)

    题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...

  4. BZOJ 3910 并查集+线段树合并

    思路: 1. 并查集+线段树合并 记得f[LCA]==LCA的时候 f[LCA]=fa[LCA] 2.LCT(并不会写啊...) //By SiriusRen #include <cstdio& ...

  5. uvalive 4730王国kingdom(并查集+线段树)

     题意:有T组測试数据.每组数据的N表示有N个城市,接下来的N行里每行给出每一个城市的坐标(0<=x,y<=1000000),然后有M(1<M<200000)个操作,操作有 ...

  6. YYHS-猜数字(并查集/线段树维护)

    题目描述     LYK在玩猜数字游戏.    总共有n个互不相同的正整数,LYK每次猜一段区间的最小值.形如[li,ri]这段区间的数字的最小值一定等于xi.     我们总能构造出一种方案使得LY ...

  7. luogu5012 水の数列 (并查集+线段树)

    如果我们能求出来每个区间个数的最大分值,那就可以用线段树维护这个东西 然后出答案了 然后这个的求法和(luogu4269)Snow Boots G非常类似,就是我们把数大小排个序,每次都拿<=x ...

  8. 【CF471E】MUH and Lots and Lots of Segments 扫描线+并查集+线段树+set

    [CF471E]MUH and Lots and Lots of Segments 题意:给你平面上n条水平或竖直的,端点在整点处的线段.你需要去掉一些线段的一些部分,使得剩下的图形:1.连通,2.无 ...

  9. bzoj 3237 连通图 - 并查集 - 线段树

    Input Output Sample Input 4 5 1 2 2 3 3 4 4 1 2 4 3 1 5 2 2 3 2 1 2 Sample Output Connected Disconne ...

随机推荐

  1. iOS -类目,延展,协议

    1.类目 类目就是为已存在的类添加新的方法.但是不能添加实例变量.比如系统的类,我们看不到他的.m文件,所以没有办法用直接添加方法的方式去实现. @interface NSMutableArray ( ...

  2. Qt 获取cmd运行结果

    http://www.cnblogs.com/gisbeginner/archive/2012/12/08/2809063.html BOOL ExecDosCmd(){ #define EXECDO ...

  3. webstorm配置scss自动编译路径

    webstorm支持sass的同步编译,也就是即写即编译,并且可以指定编译后的css的目录. 本文使用的webstorm为8.0版本 scss安装:http://www.w3cplus.com/sas ...

  4. [网络流24题]餐巾(cogs 461)

    [问题描述] 一个餐厅在相继的N天里,第i天需要Ri块餐巾(i=l,2,-,N).餐厅可以从三种途径获得餐巾. (1)购买新的餐巾,每块需p分: (2)把用过的餐巾送到快洗部,洗一块需m天,费用需f分 ...

  5. DB2 嵌入式应用中定义游标(开放平台上)

    DECLARE CURSOR statement The DECLARE CURSOR statement defines a cursor. Invocation Although an inter ...

  6. Loadrunner连接Mysql数据库

    1.库文件下载地址:http://files.cnblogs.com/files/xiaoxitest/MySQL_LoadRunner_libraries.zip 分别添加到Loadrunner b ...

  7. oracle数据库出现“批处理中出现错误: ORA-00001: 违反唯一约束条件”解决方法

    最近使用oraclede impdp工具全库导入数据库时,在数据库里面使用出现如下情况. SQL state : 违反唯一约束条件 (GDXAORCL.SYS_C0055359) ; nested e ...

  8. [LeetCode] Add Two Numbers

    You are given two linked lists representing two non-negative numbers. The digits are stored in rever ...

  9. NPOI读写Excel

    1.整个Excel表格叫做工作表:WorkBook(工作薄),包含的叫页(工作表):Sheet:行:Row:单元格Cell. 2.NPOI是POI的C#版本,NPOI的行和列的index都是从0开始 ...

  10. Centos6.5里安装Hbase(伪分布式)

    首先我们到官方网站下载Hbase,而我使用的版本是hbase-0.94.27.tar.gz 解压下来: tar zxvf hbase-.tar.gz 寻找java安装路径 [root@localhos ...