uvalive 4730王国kingdom(并查集+线段树)
题意:有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(并查集+线段树)的更多相关文章
- UVA1455 - Kingdom(并查集 + 线段树)
UVA1455 - Kingdom(并查集 + 线段树) 题目链接 题目大意:一个平面内,给你n个整数点,两种类型的操作:road x y 把city x 和city y连接起来,line fnum ...
- 并查集&线段树&树状数组&排序二叉树
超级无敌巨牛逼并查集(带权并查集)https://vjudge.net/problem/UVALive-4487 带删点的加权并查集 https://vjudge.net/problem/UVA-11 ...
- 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)
题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...
- BZOJ 3910 并查集+线段树合并
思路: 1. 并查集+线段树合并 记得f[LCA]==LCA的时候 f[LCA]=fa[LCA] 2.LCT(并不会写啊...) //By SiriusRen #include <cstdio& ...
- 并查集 + 线段树 LA 4730 Kingdom
题目传送门 题意:训练指南P248 分析:第一个操作可以用并查集实现,保存某集合的最小高度和最大高度以及城市个数.运用线段树成端更新来统计一个区间高度的个数,此时高度需要离散化.这题两种数据结构一起使 ...
- YYHS-猜数字(并查集/线段树维护)
题目描述 LYK在玩猜数字游戏. 总共有n个互不相同的正整数,LYK每次猜一段区间的最小值.形如[li,ri]这段区间的数字的最小值一定等于xi. 我们总能构造出一种方案使得LY ...
- luogu5012 水の数列 (并查集+线段树)
如果我们能求出来每个区间个数的最大分值,那就可以用线段树维护这个东西 然后出答案了 然后这个的求法和(luogu4269)Snow Boots G非常类似,就是我们把数大小排个序,每次都拿<=x ...
- 【CF471E】MUH and Lots and Lots of Segments 扫描线+并查集+线段树+set
[CF471E]MUH and Lots and Lots of Segments 题意:给你平面上n条水平或竖直的,端点在整点处的线段.你需要去掉一些线段的一些部分,使得剩下的图形:1.连通,2.无 ...
- 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 ...
随机推荐
- Python3基础笔记---序列化
1.json模块 菜鸟教程 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写. import json json.dumps json ...
- vue实现tab栏切换
html <ul class="tab"> <li v-for="(item,index) in tabs" @click="tab ...
- NOIp模拟赛二十八
(这是NOIp模拟赛?应该是NOI模拟赛不小心加了个p) 嗯,假装这是正经的NOIp模拟赛,从今天开始也写写题解吧(这几天被虐的惨惨) 今日情况:8+50+0=58 A题输出样例,B题正解写挂,C题不 ...
- sudo不用在输入密码
在任意的路径之下执行:sudo visudo 的命令对文件进行修改: 其中的: sudo ALL=(ALL) %admin ALL=(ALL) 这两个语句为: sudo ALL=(ALL) NOPAS ...
- [ZJOI2007]捉迷藏 (点分树+堆*3)
点分树一点都不会啊(还是太菜了) 点分树就是我们点分治构成的新树.满足深度很小. 然后我们就可以在上面瞎维护东西了. 三个大根堆: \(C[u]\)里装的是点分树中u的子树所有点到点分树中u的父亲的距 ...
- vue-cli 打包 使用 history模式 的后端配置
apache的配置 这是windows下的 在httpd-vhosts.conf文件中把目录指向项目index.html文件所在的位置 # Virtual Hosts # <VirtualHos ...
- 紫书 例题8-16 UVa 1608 (递归)
题意: 判断所给序列是否满足任意连续子序列中至少有一个出现一次的元素. 思路:在整体中找到一个只出现一次的元素, 然后在递归两边.因为两边的序列中有这个数那就满足要求, 所以就看剩下的序列漫步满足要求 ...
- Java基础学习总结(46)——JAVA注解快速入门
各位开发童鞋,注解这个东西我们肯定每天都能看见,也许有时候看的太多了到是会忽略注解这东西具体是如何工作的.今天在这里用最短的篇幅快速讲解下注解的原理,对这块记的不太清楚的同学也可以再次看看,下次有人详 ...
- 国庆 day 1 下午
一道图论好题(graph) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK有一张无向图G={V,E},这张无向图有n个点m条边组成.并且这是一张带权图, ...
- OpenCASCADE点向平面投影
OpenCASCADE点向平面投影 OpenCASCADE的ProjLib类提供了解析曲线(直线.圆.椭圆.抛物线.双曲线)向解析曲面(平面.圆柱面.圆锥面.球面.圆环面)投影的功能,主要用来计算三维 ...