zoukankan      html  css  js  c++  java
  • UVALive 4730 Kingdom +段树和支票托收

    主题链接:点击打开链接

    题意见白书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
    ", 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
    
    
    */


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

  • 相关阅读:
    TCP/IP断网仍然显示连通状态禁止“媒体感知”
    ASP.NET页面优化,提高载入速度方法大全
    国家气象局提供
    datatable&list<T>
    windows mobile C# net3.5 如何捕捉Arrow的CheckBox的KeyDown事件?
    hhclass 类 RAPI OpenNETCF.Desktop.Communication.DLL相关下载
    string和stringBuilder区别
    windows mobile全屏设置笔记
    CSS浮动(float,clear)通俗讲解
    js图片延时加载(jquery特效)
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4734916.html
Copyright © 2011-2022 走看看