题意:有T组測试数据。每组数据的N表示有N个城市,接下来的N行里每行给出每一个城市的坐标(0<=x,y<=1000000),然后有M(1<M<200000)个操作,操作有两类,(1)"road A B",表示将城市A和城市B通过一条道路连接,假设A和B原来属于不同的城市群。经过这个操作。A和B就在一个城市群里了。保证每条道路不会和其它道路相交(除了端点A和B)。(2)"line C"。表示查询当穿过y=C的直线,有多少个城市群、这几个城市群一共同拥有多少个城市。

思路:线段树加并查集

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<map>
#include<set>
#define eps 1e-6
#define LL long long
using namespace std; const int maxn = 100000 + 100;
const int maxl = 1000000 + 10;
const int INF = 0x3f3f3f3f;
int pa[maxn], low[maxn], high[maxn], pos[maxn], node[maxn];
int sumv1[2*maxl], addv1[2*maxl]; //有多少州
int sumv2[2*maxl], addv2[2*maxl];
int n, m;
//pa保存父亲结点,low,high保存该连通分量的上下边界。node保存连通分量中的结点个数
int find(int x) {
if(x != pa[x]) return pa[x] = find(pa[x]);
return x;
} void maintain1(int o, int L, int R) {
int lc = o*2, rc = o*2+1;
sumv1[o] = 0;
if(R > L) { //考虑左右子树
sumv1[o] = sumv1[lc] + sumv1[rc];
}
sumv1[o] += addv1[o] * (R-L+1);//考虑add操作
}
void update1(int o, int L, int R, int v, int yl, int yr) {
int lc = o*2, rc = o*2+1;
if(yl <= L && yr >= R) { //递归边界
addv1[o] += v; //累加边界的add值
} else {
int M = L + (R-L)/2;
if(yl <= M) update1(lc, L, M, v, yl, yr);
if(yr > M) update1(rc, M+1, R, v, yl, yr);
}
maintain1(o, L, R); //递归结束前又一次计算本节点的附加信息
}
int query1(int o, int L, int R, int add, int yl, int yr) {
if(yl <= L && yr >= R) {
return sumv1[o] + add*(R-L+1);
} else {
int ans = 0;
int M = L + (R-L)/2;
if(yl <= M) ans += query1(o*2, L, M, add + addv1[o], yl, yr);
if(yr > M) ans += query1(o*2+1, M+1, R, add + addv1[o], yl, yr);
return ans;
}
} void maintain2(int o, int L, int R) {
int lc = o*2, rc = o*2+1;
sumv2[o] = 0;
if(R > L) { //考虑左右子树
sumv2[o] = sumv2[lc] + sumv2[rc];
}
sumv2[o] += addv2[o] * (R-L+1);//考虑add操作
}
void update2(int o, int L, int R, int v, int yl, int yr) {
int lc = o*2, rc = o*2+1;
if(yl <= L && yr >= R) { //递归边界
addv2[o] += v; //累加边界的add值
} else {
int M = L + (R-L)/2;
if(yl <= M) update2(lc, L, M, v, yl, yr);
if(yr > M) update2(rc, M+1, R, v, yl, yr);
}
maintain2(o, L, R); //递归结束前又一次计算本节点的附加信息
}
int query2(int o, int L, int R, int add, int yl, int yr) {
if(yl <= L && yr >= R) {
return sumv2[o] + add*(R-L+1);
} else {
int ans = 0;
int M = L + (R-L)/2;
if(yl <= M) ans += query2(o*2, L, M, add + addv2[o], yl, yr);
if(yr > M) ans += query2(o*2+1, M+1, R, add + addv2[o], yl, yr);
return ans;
}
} void init() {
memset(addv1, 0 ,sizeof(addv1)); memset(addv2, 0, sizeof(addv2));
memset(sumv1, 0, sizeof(sumv1)); memset(sumv2, 0, sizeof(sumv2));
cin >> n;
for(int i = 0; i < n; i++) {
int tmp; cin >> tmp >> pos[i];
}
for(int i = 0; i < n; i++) {
pa[i] = i;
node[i] = 1;
high[i] = low[i] = pos[i];
}
cin >> m;
} void solve() {
char cmd[5];
int a, b;
float c;
while(m--) {
cin >> cmd;
if(cmd[0] == 'r') {
cin >> a >> b;
if(find(a) != find(b)) {
if(high[pa[a]] != low[pa[a]]) {
update1(1, 1, 1000000, -1, low[pa[a]]+1, high[pa[a]]);
update2(1, 1, 1000000, -node[pa[a]], low[pa[a]]+1, high[pa[a]]);
}
if(high[pa[b]] != low[pa[b]]) {
update1(1, 1, 1000000, -1, low[pa[b]]+1, high[pa[b]]);
update2(1, 1, 1000000, -node[pa[b]], low[pa[b]]+1, high[pa[b]]);
}
node[pa[a]] += node[pa[b]];
low[pa[a]] = min(low[pa[a]], low[pa[b]]);
high[pa[a]] = max(high[pa[a]], high[pa[b]]);
pa[pa[b]] = pa[a];
if(high[pa[a]] != low[pa[a]]) {
update1(1, 1, 1000000, 1, low[pa[a]]+1, high[pa[a]]);
update2(1, 1, 1000000, node[pa[a]], low[pa[a]]+1, high[pa[a]]);
}
}
} else {
cin >> c;
cout << query1(1, 1, 1000000, 0, (int)(c+1), (int)(c+1)) << " ";
cout << query2(1, 1, 1000000, 0, (int)(c+1), (int)(c+1)) << endl;
// cout << (int)(c+1) << endl;
}
}
} int main() {
// freopen("input.txt", "r", stdin);
int t; cin >> t;
while(t--) {
init();
solve();
}
return 0;
}

uvalive 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. 并查集 + 线段树 LA 4730 Kingdom

    题目传送门 题意:训练指南P248 分析:第一个操作可以用并查集实现,保存某集合的最小高度和最大高度以及城市个数.运用线段树成端更新来统计一个区间高度的个数,此时高度需要离散化.这题两种数据结构一起使 ...

  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. swift语言点评四-Closure

    总结:整个Closure的作用在于简化语言表述形式. 一.闭包的简化 Closure expression syntax has the following general form: { () -& ...

  2. [AHOI2013]差异 后缀自动机_Parent树

    题中要求: $\sum_{1\leqslant i < j \leq n } Len(T_{i}) +Len(T_{j})-2LCP(T_{i},T_{j})$ 公式左边的部分很好求,是一个常量 ...

  3. 路飞学城Python-Day17

    [1.编程范式] 1.面向过程编程 2.面向对象编程 [2.面向过程编程] 面向过程:核心就是过程   什么是过程? 过程指的是解决问题的步骤,先做什么,在作什么,面向过程就像是设计一个流水线,是一种 ...

  4. 路飞学城Python-Day10

    [37.函数-命名空间]命名空间又称为name space,顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量 x = 1,存放于内存中,那名字x存放在哪里呢?名称空间正式存放名字x和1绑定关 ...

  5. PHP XML To Array将XML转换为数组

    // Xml 转 数组, 包括根键,忽略空元素和属性,尚有重大错误 function xml_to_array( $xml ) { $reg = "/<(\\w+)[^>]*?& ...

  6. canvas 连线曲线图

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <meta name=& ...

  7. 【jQuery02】点击标题面板显示内容

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. 越努力越幸运--2-LD_PRELOAD, fork ,僵尸进程

    开始新的工作了,做了爸爸之后感觉一直都是浑浑噩噩,希望老婆和宝宝一直健康开心~ 最近遇到的问题很多啊,哈哈 1. 装环境时候,需要的glibc 版本不对,我把本地的软链接改了个别名(惯性思维),然后一 ...

  9. pandas 1 基本介绍

    import numpy as np import pandas as pd pd.Series() 构造数据 s = pd.Series([1, 3, 5, np.nan, 44, 1]) prin ...

  10. 紫书 习题 11-7 UVa 10801 (单源最短路变形)

    把每个电梯口看作一个节点, 然后计算边的权值的时候处理一下, 就ok了. #include<cstdio> #include<vector> #include<queue ...