POJ-2528

htw学长用线段树做这道,一直RE,后来发现是没有考虑子节点越界。我看这道题很像扫描线,离散化后用堆维护当前最靠前的海报,1A.

代码可比线段树短多了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<functional>
using namespace std;
struct line{
    bool operator< (const line &a)const
    {
        return no<a.no;
    }
    int x,y;
    int no;
}a[10005];
bool cmpq(line a,line b){return a.no<b.no;}
bool cmp(int i,int j){return a[i].x<a[j].x;}
int n,i,j,t,ans,tot;
int c[50005],node[10005];
bool b[10005];
void lisan()
{
    sort(c+1,c+tot+1);
    int now=1;
    for (i=2;i<=tot;i++)
      if (c[i]>c[now]) c[++now]=c[i];
    tot=now;
}
void init()
{
    ans=0; tot=0;
    memset(b,0,sizeof(b));
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        init();
        scanf("%d",&n);
        for (i=1;i<=n;i++)
        {
            scanf("%d%d",&a[i].x,&a[i].y),a[i].no=i,node[i]=i;
            c[++tot]=a[i].x; c[++tot]=a[i].x+1;
            c[++tot]=a[i].y; c[++tot]=a[i].y+1;
        }
        sort(node+1,node+n+1,cmp);
        lisan();
        j=1;
        priority_queue<line>q;
        for (i=1;i<=tot;i++)
        {
            while(!q.empty()&&q.top().y<c[i]) q.pop();
            while(j<=n&&a[node[j]].x<=c[i]) q.push(a[node[j]]),j++;
            if (!q.empty()) b[q.top().no]=1;
        }
        for (i=1;i<=n;i++) if (b[i]) ans++;
        printf("%d\n",ans);
    }
}