zoukankan      html  css  js  c++  java
  • POJ2528 计算可见线段(线段树)

    原题链接:POJ2528

    解析:这题考察的是线段树子区间更新的维护中的计算可见线段。

    用离散化,排序去重,但是这题广告是一块瓷砖一块瓷砖贴的,也就是说有可能离散化之后,明明俩个相邻点之前有空白,但是由于离散化分配序号是紧挨着的,就造成了俩块有广告瓷砖紧挨。举个例子,比如四号瓷砖(以下用号简称)和五号都有广告,那么离散化之后四号序号为1,五号为2,他们之间没别的位置,故全覆盖,那如果四号和六号有广告,但是五号没有,由于我们离散化记录的是广告左右边,故四号为1,六号为2,那么他们之间还是没空白,这就与题意不符了。所以当相邻边大于1时,序号要多+1。

    代码实例:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int maxn = 10100;
    int x[4*maxn];
    int id[10000010];
    struct CPost{
    	int l,r;
    	bool vis;
    }poster[maxn];
    struct CNode{
    	int l,r;
    	bool bCovered;
    	int Mid(){
    		return (l+r)/2;
    	}
    }tree[1000000];
    void BuildTree(int root,int l,int r){
    	tree[root].l = l;
    	tree[root].r = r;
    	tree[root].bCovered = false;
    	if(l == r)	return;
    	BuildTree(2*root+1,l,(l+r)/2);
    	BuildTree(2*root+2,(l+r)/2+1,r);
    }
    bool Push(int root,int s,int e){
    	if(tree[root].bCovered)	return false;
    	if(s == tree[root].l && e == tree[root].r){
    		tree[root].bCovered = true;
    		return true;
    	}
    	bool res;
    	if(e <= tree[root].Mid()) res = Push(2*root+1,s,e);
    	else if(s > tree[root].Mid())	res = Push(2*root+2,s,e);
    	else{
    		bool r1 = Push(2*root+1,s,tree[root].Mid());
    		bool r2 = Push(2*root+2,tree[root].Mid()+1,e);
    		res = r1 || r2;
    	}
    	if(tree[2*root+1].bCovered && tree[2*root+2].bCovered)
    		tree[root].bCovered = true;
    	return res;
    }
    
    int main()
    {
    	int t;
    	scanf("%d",&t);
    	while(t--){
    		int n,cnt;
    		scanf("%d",&n);
    		for(int i = 0;i < n;i++){
    			scanf("%d%d",&x[i],&x[i+n]);
    			poster[i].l = x[i];
    			poster[i].r = x[i+n];
    		}
    		
    		sort(x,x+2*n);
    		cnt = unique(x,x+2*n)-x;
    		int interval = 1;
    		for(int i = 0;i < cnt;i++){
    			id[x[i]] = interval;
    			if(i < cnt-1){
    				if(x[i+1] - x[i] == 1)	interval++;
    				else interval += 2;
    			}
    		}
    		BuildTree(0,1,interval);
    		int ans = 0;
    		for(int i = n-1;i >= 0;i--){
    			int s = id[poster[i].l];
    			int e = id[poster[i].r];
    			if(Push(0,s,e))	ans++;
    		}
    		printf("%d
    ",ans);
    	} 
    	return 0;
    } 
  • 相关阅读:
    iot 表索引dump《2》
    heap表和iot表排序规则不同
    Cannot complete the install because one or more required items could not be found.
    iot表输出按主键列排序,heap表不是
    iot 表主键存放所有数据,且按数据插入顺序排序
    iot表和heap表排序规则不同
    org.eclipse.graphiti.ui.editor.DiagramEditorInput.
    Oracle 排序规则
    perl 异步超时 打印错误
    14.6.3 Grouping DML Operations with Transactions 组DML操作
  • 原文地址:https://www.cnblogs.com/long98/p/10352196.html
Copyright © 2011-2022 走看看