poj 2528 Mayor's posters 线段数+离散化

来源:互联网 发布:mysql当前时间转成毫秒 编辑:程序博客网 时间:2024/05/15 20:21
http://poj.org/problem?id=2528
题意: 给n个广告纸,先给的先按位置贴在墙上 后给的可以覆盖前面的广告
问,最后能看到多少广告纸,看不全也算看到
由于广告纸的长度范围太大,1~1千万     
纯线段树 TL + ML   但是 注意到广告纸最多有十万。
这样我们就可以离散化,把一个大的区间离散到一个小的区间里面
例如:  n = 3  区间为 1 10, 1 4, 6 10。
1  4  6 10
1  2  3  4
我们可以把输入的4离散到2中  
样例就成为
1 4
1 2
3 4
但是这样的离散方式是不对的
这样离散出来的结果是2  但正确答案应该为 3
正确的离散方式应为
1 4 5 6 10
1 2 3 4 5
在中间加一个5 就可以防止这样的现象发生。
利用离散化的线段树和hash的标记 就可以

注意在离散的时候 用二分快速的去找到你已经离散的真正标号。

代码:

#include <set>#include <map>#include <queue>#include <stack>#include <deque>#include <math.h>#include <string>#include <vector>#include <stdio.h>#include <iostream>#include <string.h>#include <algorithm>#include <functional>#define mem(a) memset(a,0,sizeof(a));#define mem_1(a) memset(a,-1,sizeof(a));#define sf(a) scanf("%d",&a)#define sff(a,b) scanf("%d%d",&a,&b)#define sfff(a,b,c) scanf("%d%d%d",&a,&b,&c)const int INF = 0x7FFFFFFF;const int MAXN = 10100;const double PI = acos(-1.0);const double esp = 1e-10;using namespace std;struct node{    int l,r,num,lazy;    int mid()    {        return (l+r)>>1;    }}Tree[MAXN<<4];int Hash[MAXN<<3];int Rdata[MAXN],Ldata[MAXN];int data[MAXN<<2];int ans = 0;int flag[MAXN<<2];void pushDown(int i){    if(Tree[i].lazy > 0)    {        Tree[i << 1].lazy = Tree[i].lazy;        Tree[i<<1|1].lazy = Tree[i].lazy;        Tree[i].lazy = 0;    }}void build_tree(int l,int r,int i){    Tree[i].l = l;    Tree[i].r = r;    Tree[i].lazy = 0;    if(r==l)    {        Tree[i].num = 0;        return ;    }    int mid = (l+r)>>1;    build_tree(l,mid,i<<1);    build_tree(mid+1,r,i<<1|1);}void updata(int l,int r,int i,int k){    if(Tree[i].l == l && Tree[i].r == r)    {        Tree[i].lazy = k;        return ;    }    pushDown(i);    int mid = Tree[i].mid();    if(r <= mid) updata(l,r,i<<1,k);    else if(mid < l) updata(l,r,i<<1|1,k);    else{        updata(l,mid,i<<1,k);        updata(mid+1,r,i<<1|1,k);    }}void Query(int l,int r,int i){    if(l == r)    {        if(!flag[Tree[i].lazy] && Tree[i].lazy)        {            flag[Tree[i].lazy] = 1;            ans++;        }        return ;    }    pushDown(i);    int mid = Tree[i].mid();    Query(l,mid,i<<1);    Query(mid+1,r,i<<1|1);}int Find(int l,int r,int aim){    while(l<=r){        int mid = ( l + r) >> 1;        if(Hash[mid] == aim) return mid;        if(Hash[mid] > aim)            r = mid - 1;        else            l = mid + 1;    }    return -1;}int main(){    int T,n,x,y;    sf(T);    while(T--)    {        sf(n);        int cnt = 0;        ans = 0;        data[0] = 0;        mem(flag);       // mem(Tree);        for(int i=1;i<=n;i++)        {            sff(Ldata[i],Rdata[i]);            data[++cnt] = Ldata[i];            data[++cnt] = Rdata[i];        }        sort(data+1,data+1+cnt);        int count = 0;        for(int i=1;i<=cnt;i++)        {            if(data[i]!=data[i-1]) Hash[++count] = data[i];        }        int count1 = count;        for(int i=2;i<=count;i++)        {            if(Hash[i] - Hash[i-1] > 1) Hash[++count1] = Hash[i] - 1;        }        count = count1;        sort(Hash+1,Hash+1+count);        build_tree(1,count,1);        for(int i=1;i<=n;i++)        {            int l = Find(1,count,Ldata[i]);            int r = Find(1,count,Rdata[i]);            updata(l,r,1,i);        }        Query(1,count,1);        printf("%d\n",ans);    }    return 0;}/*
样例231 101 46 1051 42 68 103 47 10*/

0 0