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