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);
}
}