LA4730,Kingdom 线段树+并查集

来源:互联网 发布:网页mp4下载软件 编辑:程序博客网 时间:2024/04/29 21:18
There were n cities in an ancient kingdom. In the beginning of the  kingdom, all cities were isolated. Kings ordered their subjects to  construct roads connecting cities. A lot of roads were built with time.  Every road was always constructed along the line segment between two  cities. All cities are partitioned into disjoint components of cities  by road-connectivity. A connected component of cities was called a  state. A state consists of cities and roads connecting them.

A historical record tells a time sequence of road constructions in  order. A road connecting two citiesA andB doesn't intersect with  other roads at a point except forA andB. Before construction,A  andB may have belonged to the same state or different states. After  construction,A andB would belong to a same state, i.e., two states  would merge into a state if needed.

Prof. Kim, a historian, is concerned about the following question: How  many states does a horizontal line (corresponding to the latitude of a  specific place) pass by at a moment of the past? The figure below shows  an example of a configuration of roads at some moment. A circle  represents a city and a line segment represents a road between two  cities. There are 3 states. A line with y = 4.5 passes by two states  with total 8 cities and a line with y = 6.5 passes by one state with 5  cities.

\epsfbox{p4730.eps}

You are to write a program which handles the following two types of  commands:


  • road A B

    A road between two cities A and B will  be constructed. The road doesn't intersect with other roads at a point  except forA andB. This is an informative command and your program  does not need to respond.

  • line C

    This is a query. The program should output  the number of states which a line y = C passes by and the total number  of cities of them.

Input

Your program is to read from standard input. The input consists of T  test cases. The number of test cases T is given in the first line of  the input. The first line of each test case contains an integern, the  number of cities, where1$ \le$n$ \le$100, 000. Each of the following n  lines contains two integersx andy (0$ \le$x,y$ \le$1, 000, 000),  where(x, y) represents the coordinate of a city. There is a single  space between the integers. The cities are numbered from 0 ton - 1 in  order. The next line contains an integerm, the number of commands,  where1$ \le$m$ \le$200, 000. Each of the following m lines contains a  command, either ``roadA B" or ``lineC", where0$ \le$A$ \neq$B < n and C (0 < C < 1, 000, 000) is a real number of  which the fractional part is always 0.5. There exists at most one road  construction connecting a pair of cities and there exists at least one  query per a test case.

Output

Your program is to write to standard output. Print exactly one line for  a query through all test cases. The line should contain two integers  which represent the number of states and the total number of cities of  them respectively.

The following shows sample input and output for three test cases.

Sample Input

3 10 1 7 5 7 8 6 3 5 5 5 2 3 10 3 7 2 4 1 11 1 11 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 1 100 100 1 line 100.5 2 10 10 20 20 2 road 0 1 line 15.5

Sample Output

0 0 2 8 1 5 0 0 1 2

做完看了下排名、、Rank2。。真开心~!!

转载请注明出处:http://blog.csdn.net/scut_pein/article/details/20218565

题意:平面上有n个城市,初始时城市之间没有任何双向道路相连。你的任务是一次执行以下指令。

road A B:在城市A和B之间连一条双向道路,保证这条道路不和其他道路在非端点处相交。

line C:询问一条Y=C的水平线和多少个州相交,以及这些州一共柏寒多少座城市。

思路:并查集+线段树
并查集要维护这个州的最小Y值和最大Y值,以及这个州有多少个城市
当要连一条边:如果已经在一个州,不处理
如果不在一个州,那么要删除原先的两个州(祖先的秩>1才删,=1表示是个点而已),再建立一个更大范围的州
删州对应着线段树上的区间减。
询问的时候只要在线段树上找即可得到州的数目,以及城市的数目

 

#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define maxn 2000080#define maxm 100080int father[maxm],rank1[maxm],miny[maxm],maxy[maxm],y[maxm];#define lson id<<1,l,mid#define rson id<<1|1,mid+1,rint find(int x){if(x == father[x])return x;return father[x] = find(father[x]);}struct ST{int l,r,add,city;}st[maxn<<2];void buildtree(int id,int l,int r){st[id].l = l,st[id].r = r;st[id].add = st[id].city = 0;if(l == r)return;int mid = (l + r) >> 1;buildtree(lson);buildtree(rson);}void PushDown(int id){if(st[id].add){st[id<<1].add += st[id].add;st[id<<1|1].add += st[id].add;st[id].add = 0;}if(st[id].city){st[id<<1].city += st[id].city;st[id<<1|1].city += st[id].city;st[id].city = 0;}}void Update(int id,int l,int r,int add,int c){if(st[id].l == l && st[id].r == r){st[id].add += add;st[id].city += c;return;}PushDown(id);if(st[id<<1].r >= r)Update(id<<1,l,r,add,c);else if(st[id<<1|1].l <= l)Update(id<<1|1,l,r,add,c);else {Update(id<<1,l,st[id<<1].r,add,c);Update(id<<1|1,st[id<<1|1].l,r,add,c);}}void Union(int a,int b){int fa = find(a),fb = find(b);if(fa == fb)return;//接下来就是得先删除两个小州,建立一个大州。得是州才能删,点是不能删的if(rank1[fa] > 1)Update(1,miny[fa],maxy[fa],-1,-rank1[fa]);if(rank1[fb] > 1)Update(1,miny[fb],maxy[fb],-1,-rank1[fb]);//建立一个大州father[fa] = fb;rank1[fb] += rank1[fa];miny[fb] = min(miny[fa],miny[fb]);maxy[fb] = max(maxy[fa],maxy[fb]);Update(1,miny[fb],maxy[fb],1,rank1[fb]);}void init(int n){for(int i = 0;i < n;i++){father[i] = i;rank1[i] = 1;miny[i] = maxy[i] = y[i];}}int query(int id,int pos){if(st[id].l == pos && st[id].r == pos){return id;}PushDown(id);if(st[id<<1].r >= pos)return query(id<<1,pos);else return query(id<<1|1,pos);}int main(){//freopen("in.txt","r",stdin);int t;scanf("%d",&t);while(t--){int n;scanf("%d",&n);int len = 0;for(int i = 0;i < n;i++){int x;scanf("%d%d",&x,&y[i]);y[i]<<=1;len = max(len,y[i]);}init(n);buildtree(1,0,len);int m;scanf("%d",&m);char ope[10];int u,v;double c;while(m--){scanf("%s",ope);if(ope[0] == 'r'){scanf("%d%d",&u,&v);Union(u,v);}else {scanf("%lf",&c);c*=2;if(c > len){printf("0 0\n");continue;}int pos = query(1,(int)c);printf("%d %d\n",st[pos].add,st[pos].city);}}}return 0;}


 

0 0
原创粉丝点击