zoukankan      html  css  js  c++  java
  • POJ 1436 Horizontally Visible Segments(线段树)

    POJ 1436 Horizontally Visible Segments

    题目链接

    线段树处理染色问题,把线段排序。从左往右扫描处理出每一个线段能看到的右边的线段,然后利用bitset维护枚举两个线段。找出还有一个两个都有的线段

    代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <bitset>
    #include <vector>
    using namespace std;
    
    const int N = 8005;
    bitset<N> g[N];
    int t, n;
    
    struct Seg {
    	int x, y1, y2;
    	void read() {
    		scanf("%d%d%d", &y1, &y2, &x);
    	}
    } s[N];
    
    bool cmp(Seg a, Seg b) {
    	return a.x < b.x;
    }
    
    #define lson(x) ((x<<1)+1)
    #define rson(x) ((x<<1)+2)
    
    struct Node {
    	int l, r, val, setv;
    } node[N * 4 * 2];
    
    void pushup(int x) {
    	if (node[lson(x)].val == node[rson(x)].val) node[x].val = node[lson(x)].val;
    	else node[x].val = -1;
    }
    
    void pushdown(int x) {
    	if (node[x].setv != -1) {
    		node[lson(x)].val = node[rson(x)].val = node[x].setv;
    		node[lson(x)].setv = node[rson(x)].setv = node[x].setv;
    		node[x].setv = -1;
    	}
    }
    
    void build(int l, int r, int x = 0) {
    	node[x].l = l; node[x].r = r; node[x].val = -1; node[x].setv = -1;
    	if (l == r)
    		return;
    	int mid = (l + r) / 2;
    	build(l, mid, lson(x));
    	build(mid + 1, r, rson(x));
    }
    
    vector<int> g2[N];
    
    void add(int l, int r, int v, int x = 0) {
    	if (node[x].val != -1 && node[x].l >= l && node[x].r <= r) {
    		if (g[node[x].val][v] == false)
    			g2[node[x].val].push_back(v);
    		g[node[x].val][v] = true;
    		node[x].setv = v;
    		node[x].val = v;
    		return;
    	}
    	if (node[x].l == node[x].r) {
    		node[x].val = v;
    		return;
    	}
    	pushdown(x);
    	int mid = (node[x].l + node[x].r) / 2;
    	if (l <= mid) add(l, r, v, lson(x));
    	if (r > mid) add(l, r, v, rson(x));
    	pushup(x);
    }
    
    int main() {
    	scanf("%d", &t);
    	while (t--) {
    		scanf("%d", &n);
    		for (int i = 0; i < n; i++) {
    			g[i].reset();
    			g2[i].clear();
    			s[i].read();
    		}
    		sort(s, s + n, cmp);
    		build(0, N * 2 - 1);
    		for (int i = 0; i < n; i++)
    			add(s[i].y1 * 2, s[i].y2 * 2, i);
    		int ans = 0;
    		for (int i = 0; i < n; i++) {
    			for (int j = 0; j < g2[i].size(); j++) {
    				if (g[i][g2[i][j]])
    					ans += (g[i]&g[g2[i][j]]).count();
    			}
    		}
    		printf("%d
    ", ans);
    	}
    	return 0;
    }


  • 相关阅读:
    PHP保留小数的相关方法
    ASP.NET Core MVC 之过滤器(Filter)
    ASP.NET Core MVC 之控制器(Controller)
    ASP.NET Core MVC 之视图组件(View Component)
    ASP.NET Core MVC 之局部视图(Partial Views)
    标签助手(TagHelper)
    ASP.NET Core MVC 之布局(Layout)
    ASP.NET Core MVC 之视图(Views)
    ASP.NET Core MVC 之模型(Model)
    九卷读书:淘宝从小到大的发展 -重读《淘宝技术这十年》
  • 原文地址:https://www.cnblogs.com/twodog/p/12139904.html
Copyright © 2011-2022 走看看