POJ 2528 Mayor's posters

来源:互联网 发布:中信淘宝信用卡怎么办 编辑:程序博客网 时间:2024/04/29 02:30

题目链接:http://poj.org/problem?id=2528


题意:有N张海报,每张海报贴在[L,R]的区间上,问最后还能看见多少张海报


思路:一开始在纠结如何保存一个区间有多少张海报,上一次填色的题目因为数据少,可以用二进制保存,这次数据非常大,不过因为只查询一次,直接遍历一次线段树就可以了,不过需要离散化,注意离散化的时候之间隔了1个数以上的2个数离散化时也要隔一个数,不然会出错(数组要开10倍RE了……开20倍就过了)

比如 :1  7            1  4

            1  2     ->    1  2

            4  7            3  4

这样离散明显不对的,正确的是:

            1  7            1  5

            1  2     ->    1  2

            4  7            4  5


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define maxn 10030using namespace std;struct Tree{    int l,r,date;}tree[maxn*20];int lazy[maxn*20],post[maxn*20][2],temp[maxn*20],vis2[maxn*20],vis[maxn*1000],res;void build(int root,int l,int r){    tree[root].l=l;    tree[root].r=r;    if (l==r) return;    int mid=(l+r)>>1;    build(root<<1,l,mid);    build(root<<1|1,mid+1,r);}void update(int root,int l,int r,int val){    if (tree[root].l>=l && tree[root].r<=r)    {        lazy[root]=val;        return;    }    if (lazy[root]!=0)    {        lazy[root<<1]=lazy[root];        lazy[root<<1|1]=lazy[root];        lazy[root]=0;    }    int mid=(tree[root].l+tree[root].r)>>1;//    if (l<=mid) update(root<<1,l,r,val);    if (r>mid) update(root<<1|1,l,r,val);}void que(int root){    if (lazy[root]!=0)    {        if (vis2[lazy[root]]==0)        {            res++;            vis2[lazy[root]]=1;        }        return;    }    if (tree[root].l==tree[root].r) return;    que(root<<1);    que(root<<1|1);}int main(){    int t,n;    scanf("%d",&t);    while (t--)    {        scanf("%d",&n);        int cnt=0;        memset(vis,0,sizeof(vis));        memset(vis2,0,sizeof(vis2));        memset(lazy,0,sizeof(lazy));        for (int i=0;i<n;i++)        {            scanf("%d%d",&post[i][0],&post[i][1]);            if (!vis[post[i][0]])            {              temp[cnt++]=post[i][0];              vis[post[i][0]]=1;            }            if (!vis[post[i][1]])            {              temp[cnt++]=post[i][1];              vis[post[i][1]]=1;            }        }        sort(temp,temp+cnt);        int map=0;        for (int i=0;i<cnt;i++)        {          vis[temp[i]]=++map;          if (temp[i+1]-temp[i]>1) map++;        }        build(1,1,vis[temp[cnt-1]]);        for (int i=0;i<n;i++)        {            int a=vis[post[i][0]],b=vis[post[i][1]];            update(1,a,b,i+1);        }        res=0;        que(1);        cout<<res<<endl;    }}



0 0