• POJ 2528 Mayor's posters 离散化和线段树题解


    本题就是要往墙上贴海报,问最后有多少可见的海报。

    事实上本题的难点并非线段树,而是离散化。

    由于数据非常大,直接按原始数据计算那么就会爆内存和时间的。

    故此须要把数据离散化。

    比方有海报1 6   7 9   20 100  5 1000的原始数据。直接计算须要1-1000的内存,离散化之后仅仅须要8内存,由于仅仅有4组数据8个数。

    本题更进一步高级一点的离散化就是须要把不相邻的两个数据插入一个数值。表示有空白的地方,不是全部海报都覆盖到的。

    比方上面的数据要离散为:1 2  5 6  7 8 9 10 20 21 100 101 1000,中间插入了一些数值,这样才干保证数据正确。

    比較难想出来的地方。须要好好考虑一下才干想通的。

    看程序discreteArr是离散化之后的数据。使用这种数据处理就能够比原始数据少非常多数据了。


    #include <stdio.h>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int SIZE = 10005;
    bool hashColor[SIZE];
    int le[SIZE], ri[SIZE];
    int discreteArr[SIZE<<2];//由于这里或许须要四倍的SIZE内存
    int seg[SIZE<<4];
    int visiblePosts;
    
    inline int lChild(int rt) { return rt<<1; }
    inline int rChild(int rt) { return rt<<1|1; }
    
    inline void pushDown(int rt)
    {
    	if (seg[rt])
    	{
    		seg[lChild(rt)] = seg[rChild(rt)] = seg[rt];
    		seg[rt] = 0;
    	}
    }
    
    void build(int l, int r, int rt)
    {
    	seg[rt] = 0;
    	if (l == r) return ;
    	int m = l + ((r-l)>>1);
    	build(l, m, lChild(rt));
    	build(m+1, r, rChild(rt));
    }
    
    void update(int ql, int qr, int col, int l, int r, int rt)
    {
    	if (ql <= l && r <= qr)
    	{
    		seg[rt] = col;
    		return;
    	}
    	pushDown(rt);
    	int m = l + ((r-l)>>1);
    	if (ql <= m) update(ql, qr, col, l, m, lChild(rt));
    	if (m < qr) update(ql, qr, col, m+1, r, rChild(rt));
    }
    
    void query(int l, int r, int rt)
    {
    	if (seg[rt])
    	{
    		if (!hashColor[seg[rt]])
    		{
    			visiblePosts++;
    			hashColor[seg[rt]] = true;
    		}
    		return ;
    	}
    	if (l == r) return ;//注意这里没有poster的时候
    	int m = l + ((r-l)>>1);
    	query(l, m, lChild(rt));
    	query(m+1, r, rChild(rt));
    }
    
    int biSearch(int arr[], int key, int n)
    {
    	int l = 1, r = n-1, m = -1;
    	while (l <= r)
    	{
    		m = l + ((r-l)>>1);
    		if (arr[m] < key) l = m+1;
    		else if (key < arr[m]) r = m-1;
    		else break;
    	}
    	return m;
    }
    
    int main()
    {
    	int T, n;
    	scanf("%d", &T);
    	while (T--)
    	{
    		scanf("%d", &n);
    		int disN = 1;
    		for (int i = 1; i <= n; i++)
    		{
    			scanf("%d %d", &le[i], &ri[i]);
    			discreteArr[disN++] = le[i];
    			discreteArr[disN++] = ri[i];
    		}
    		sort(discreteArr+1, discreteArr+disN);
    
    		int j = 2;
    		for (int i = 2; i < disN; i++)
    		{
    			if (discreteArr[i] != discreteArr[i-1]) 
    				discreteArr[j++] = discreteArr[i];
    		}
    		for (int i = j-1; i > 1; i--)
    		{
    			if (discreteArr[i] != discreteArr[i-1] + 1)
    				discreteArr[j++] = discreteArr[i-1] + 1;
    		}
    		sort(discreteArr + 1, discreteArr + j);
    		build(1, j-1, 1);
    		for (int i = 1; i <= n; i++)
    		{
    			int ql = biSearch(discreteArr, le[i], j);
    			int qr = biSearch(discreteArr, ri[i], j);
    			update(ql, qr, i, 1, j-1, 1);
    		}
    		visiblePosts = 0;
    		memset(hashColor, 0, sizeof(bool) * (n+1));
    		query(1, j-1, 1);
    		printf("%d
    ", visiblePosts);
    	}
    	return 0;
    }
    
    
    


  • 相关阅读:
    Canvas与Paint的0基础使用
    PHP经常使用功能
    java枚举在android项目应用
    POJ1833 &amp; POJ3187 &amp; POJ3785 next_permutation应用
    usb芯片调试经验
    Equals和==比較
    JSTL标准标签库具体解释
    零基础学python-3.3 标识符
    用react native 做的一个推酷client
    Linux异常关机后,Mysql启动出错ERROR 2002 (HY000)
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/6925802.html
Copyright © 2020-2023  润新知