主题链接:点击打开链接

题意见白书P248

思路:

先把读入的y值都扩大2倍变成整数

然后离散化一下

用线段树来维护y轴 区间上每一个点的 城市数量和联通块数量。

然后用并查集维护每一个联通块及联通块的最大最小y值。还要加并查集的秩来记录每一个联通块的点数

然后就是模拟搞。

T^T绝杀失败题。。似乎数组开小了一点就过了。==

#include<stdio.h>
#include<math.h>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
#define rank Rank
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define Lson(x) tree[x].l
#define Rson(x) tree[x].r
#define Sum0(x) tree[x].sum[0]
#define Lazy0(x) tree[x].lazy[0]
#define Sum1(x) tree[x].sum[1]
#define Lazy1(x) tree[x].lazy[1]
inline int Mid(int x, int y){return (x+y)>>1;}
#define N 100005
struct Point{
int x, y;
}p[100005];
struct que{
int u, v, op;
}Q[200005];
vector<int>G;
int n, q;
char s[10]; struct node{
int l, r, sum[2], lazy[2];
}tree[N<<4];
void push_down(int id){
if(Lazy1(id)) {
Sum1(L(id)) += Lazy1(id);
Sum1(R(id)) += Lazy1(id);
Lazy1(L(id)) += Lazy1(id);
Lazy1(R(id)) += Lazy1(id);
Lazy1(id) = 0;
}
if(Lazy0(id)) {
Sum0(L(id)) += Lazy0(id);
Sum0(R(id)) += Lazy0(id);
Lazy0(L(id)) += Lazy0(id);
Lazy0(R(id)) += Lazy0(id);
Lazy0(id) = 0;
}
}
void push_up(int id){Sum0(id) = Sum0(L(id)) + Sum0(R(id));Sum1(id) = Sum1(L(id)) + Sum1(R(id));}
void build(int l, int r, int id){
Lson(id) = l; Rson(id) = r;
Sum0(id) = Lazy0(id) = Sum1(id) = Lazy1(id) = 0;
if(l == r) return ;
int mid = Mid(l, r);
build(l, mid, L(id));
build(mid+1, r, R(id));
}
void updata(int l, int r, int val, int now, int id){
push_down(id);
if(l == Lson(id) && Rson(id) == r) {
if(now==0)Sum0(id) += val, Lazy0(id) += val;
else Sum1(id) += val, Lazy1(id) += val;
return ;
}
int mid = Mid(Lson(id), Rson(id));
if(mid < l)
updata(l, r, val, now, R(id));
else if(r <= mid)
updata(l, r, val, now, L(id));
else {
updata(l, mid, val, now, L(id));
updata(mid+1, r, val, now, R(id));
}
push_up(id);
}
int query(int pos, int now, int id){
push_down(id);
if(Lson(id)==Rson(id))if(now==0)return Sum0(id); else return Sum1(id);
int mid = Mid(Lson(id), Rson(id));
int ans;
if(mid < pos)
return query(pos, now, R(id));
else return query(pos, now, L(id));
}
int f[100005], rank[100005], S[100005], X[100005]; //每一个集合的上下界
int find(int x){return x==f[x]?x:f[x] = find(f[x]);}
void Union(int x, int y){
int fx = find(x), fy = find(y);
if(fx == fy)return;
if(S[fx] > S[fy]) swap(fx, fy);
if(S[fx] <= X[fy]){
updata(S[fx], X[fy], 1, 0, 1);
updata(S[fx], X[fy], rank[fx] + rank[fy], 1, 1);
updata(X[fx], S[fx], rank[fy], 1, 1);
updata(X[fy], S[fy], rank[fx], 1, 1);
}
else if(X[fx] >= X[fy]) {
updata(X[fx], S[fx], -1, 0, 1);
updata(X[fy], X[fx], rank[fx], 1, 1);
updata(S[fx], S[fy], rank[fx], 1, 1);
}
else {
updata(X[fy], S[fx], -1, 0, 1);
updata(X[fx], X[fy], rank[fy], 1, 1);
updata(S[fx], S[fy], rank[fx], 1, 1);
}
if(rank[fy]<rank[fx])swap(fx, fy);
f[fx] = fy;
rank[fy] += rank[fx];
rank[fx] = 0;
X[fy] = min(X[fy], X[fx]);
S[fy] = max(S[fy], S[fx]);
} void input(){
G.clear();
scanf("%d", &n);
for(int i = 1; i <= n; i++) f[i] = i, rank[i] = 1;
for(int i = 1; i <= n; i++) scanf("%d %d",&p[i].x, &p[i].y), p[i].y <<= 1, G.push_back(p[i].y);
scanf("%d", &q);
for(int i = 0; i < q; i++)
{
scanf("%s", s);
if(s[0]=='r')
{
Q[i].op = 1;
scanf("%d %d", &Q[i].u, &Q[i].v); Q[i].u++; Q[i].v++;
}
else {
Q[i].op = 2;
scanf("%d.5",&Q[i].u);
Q[i].u = Q[i].u * 2+1;
G.push_back(Q[i].u);
}
}
sort(G.begin(), G.end());
G.erase(unique(G.begin(), G.end()), G.end());
for(int i = 1; i <= n; i++)X[i] = S[i] = p[i].y = lower_bound(G.begin(), G.end(), p[i].y) - G.begin()+1;
for(int i = 0; i < q; i++)if(Q[i].op == 2)Q[i].u = lower_bound(G.begin(), G.end(), Q[i].u) - G.begin()+1;
}
int main() {
int T; scanf("%d",&T);
while(T--){
input();
build(1, G.size(), 1);
for(int i = 0; i < q; i++) {
if(Q[i].op == 1)
{
Union(Q[i].u, Q[i].v);
}
else
printf("%d %d\n", query(Q[i].u, 0, 1), query(Q[i].u, 1, 1));
}
}
return 0;
}
/*
3
11
1 7
5 7
8 6
3 5
5 5
2 3
10 3
7 2
4 1
11 1
4 6
21
road 0 1
road 3 5
line 6.5
road 4 2
road 3 8
road 4 7
road 6 9
road 4 1
road 2 7
line 4.5
line 6.5
line 3.5
line 2.5
line 5.5
road 10 0
line 5.5
line 6.5
road 0 3
line 1.5
line 6.5
line 2.5 ans:
0 0
2 8
1 5
2 8
3 10
1 5
1 6
1 6
2 11
1 9
2 11 */

版权声明:本文博客原创文章,博客,未经同意,不得转载。

UVALive 4730 Kingdom +段树和支票托收的更多相关文章

  1. BZOJ-3212 Pku3468 A Simple Problem with Integers 裸线段树区间维护查询

    3212: Pku3468 A Simple Problem with Integers Time Limit: 1 Sec Memory Limit: 128 MB Submit: 1278 Sol ...

  2. ZOJ 1610 间隔染色段树

    要长8000仪表板.间染色的范围,问:最后,能看到的颜色,而且颜色一共有段出现 覆盖段 数据对比水   水可太暴力 段树: #include "stdio.h" #include ...

  3. HDU 1394 Minimum Inversion Number (数据结构-段树)

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  4. PKU A Simple Problem with Integers (段树更新间隔总和)

    意甲冠军:一个典型的段树C,Q问题,有n的数量a[i] (1~n),C, a, b,c在[a,b]加c Q a b 求[a,b]的和. #include<cstdio> #include& ...

  5. BZOJ 2588 Count on a tree (COT) 是持久的段树

    标题效果:两棵树之间的首次查询k大点的权利. 思维:树木覆盖树,事实上,它是正常的树木覆盖了持久段树. 由于使用权值段树可以寻求区间k大,然后应用到持久段树思想,间隔可以做减法.详见代码. CODE: ...

  6. lintcode-439-线段树的构造 II

    439-线段树的构造 II 线段树是一棵二叉树,他的每个节点包含了两个额外的属性start和end用于表示该节点所代表的区间.start和end都是整数,并按照如下的方式赋值: 根节点的 start ...

  7. lintocde-247-线段树的查询 II

    247-线段树的查询 II 对于一个数组,我们可以对其建立一棵 线段树, 每个结点存储一个额外的值 count 来代表这个结点所指代的数组区间内的元素个数. (数组中并不一定每个位置上都有元素) 实现 ...

  8. lintcode-203-线段树的修改

    203-线段树的修改 对于一棵 最大线段树, 每个节点包含一个额外的 max 属性,用于存储该节点所代表区间的最大值. 设计一个 modify 的方法,接受三个参数 root. index 和 val ...

  9. lintcode-202-线段树的查询

    202-线段树的查询 对于一个有n个数的整数数组,在对应的线段树中, 根节点所代表的区间为0-n-1, 每个节点有一个额外的属性max,值为该节点所代表的数组区间start到end内的最大值. 为Se ...

随机推荐

  1. 苹果Swift编程语言新手教程【中文版】

    文件夹 1 简单介绍 2 Swift入门 3 简单值 4 控制流 5 函数与闭包 6 对象与类 7 枚举与结构 1 简单介绍 Swift是供iOS和OS X应用编程的新编程语言,基于C和Objecti ...

  2. Entity Framework mvc Code First data migration

    1. Code First 可以先在代码里写好数据模型,自动生成DB.下一次启动的时候会根据__MigrationHistory判断 数据库是否和模型一致. 详情参考:http://blogs.msd ...

  3. 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)

    原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...

  4. 《编程简介(Java) &#183;10.3递归思想》

    <编程简介(Java) ·10.3递归思想> 10.3.1 递归的概念 以两种方式的人:男人和女人:算法是两种:递归迭代/通知: 递归方法用自己的较简单的情形定义自己. 在数学和计算机科学 ...

  5. synchronized与static synchronized 差异

    1.synchronized与static synchronized 差异       synchronized是对类的当前实例进行加锁,防止其它线程同一时候訪问该类的该实例的全部synchroniz ...

  6. JavaScript IDE

    哪些JavaScript IDE最好用?   阅读本文之前,分享大家一张图片,看图会发现JavaScript开发需求最高,占比达到42.84%,因此掌握JavaScript语言好工作就不愁啦,工欲善其 ...

  7. Zen Coding css,html缩写替换大观 快速写出html,css

    阅读本文,先仔细阅读网站文章. Zen Coding 快速编写HTML/CSS代码的实现 复制代码 代码如下:E 元素名称(div, p); E#id 使用id的元素(div#content, p#i ...

  8. java 二维码原理以及用java实现的二维码的生成、解码(转)

    http://blog.csdn.net/songylwq/article/details/8643948 http://sjsky.iteye.com/blog/1136934 http://bbs ...

  9. hdu 5077 NAND(暴力打表)

    题目链接:hdu 5077 NAND 题目大意:Xiaoqiang要写一个编码程序,然后依据x1,x2,x3的值构造出8个字符.如今给定要求生成的8个字符.问 说Xiaoqiang最少要写多少行代码. ...

  10. hdu4362 dp + 单调队列优化

    dp传输方程很easy需要 dp[i][j] = min{dp[i - 1][k] + abs(pos[i][j] -pos[i - 1][j]) + cost[i][j]} n行m一排 每个传输扫描 ...