题意:有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. Vue export和import

    config/index.js export default '123456'; import strs from '@/config';   //此处直接写@config就可以, 如果是export ...

  2. 通过nodeSelector配置项实现pod部署至指定node

    Node节点添加标签 [root@node1 work]# kubectl label nodes node1 node=master --overwrite node/node1 labeled [ ...

  3. linux VNC-server

    [root@kvm-server Packages]# rpm -qpi tigervnc-server-1.8.0-1.el7.x86_64.rpm Name : tigervnc-server V ...

  4. 阿里云部署java项目

    第一步:注册阿里云账号(如果有请看第二步) 1.百度搜索阿里云,点击进入阿里云官网 2.点击右上角免费注册 3.进入注册页面,按照要求填写信息 4.注册完成后登陆 登陆之后首先购买阿里云esc与服务器 ...

  5. win10 64位下VirtualBox安装CentOS6.9

    第一步:安装VritualBox 百度“VritualBox”下载安装即可: 第二步:下载Linux镜像系统并安装 这里写出我参照的博客,很详细,我就不累赘了! 原文地址:http://blog.cs ...

  6. pandas 6 合并数据 concat, append 垂直合并,数据会变高/长

    from __future__ import print_function import pandas as pd import numpy as np concatenating # ignore ...

  7. 精品JS代码收藏大全

    1. oncontextmenu="window.event.returnvalue=false" 将彻底屏蔽鼠标右键 <table border oncontextmenu ...

  8. 10gR2 rac怎样重跑root.sh ?

    原文博客链接地址:10gR2 rac怎样重跑root.sh ? 前几天遇到一客户的10205 rac,出现LMD进程IPC SEND TIMEOUT问题. 准备深入研究下Oracle RAC 的LMO ...

  9. The in operator

    The operators we have seen so far are all special characters like + and *, but there are a few opera ...

  10. 基于分布式的短文本命题实体识别之----人名识别(python实现)

    目前对中文分词精度影响最大的主要是两方面:未登录词的识别和歧义切分. 据统计:未登录词中中文姓人名在文本中一般只占2%左右,但这其中高达50%以上的人名会产生切分错误.在所有的分词错误中,与人名有关的 ...