CodeForces 652D Nested Segments
离散化+树状数组
先对坐标离散化,把每条线段结尾所在点标1,
询问某条线段内有几条线段的时候,只需询问这段区间的和是多少,询问结束之后再把这条线段尾部所在点标为0
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<algorithm> using namespace std; const int maxn=2*1e5+10; struct X { int x,y,ans,id; }p[2*maxn]; int n; int lsh[2*maxn],tot; int c[2*maxn]; bool cmp(const X&a,const X&b) { return a.x<b.x; } bool cmp2(const X&a,const X&b) { return a.id<b.id; } int lowbit(int x) { return x&(-x); } void update(int pos,int val) { while(pos<=2*n) { c[pos]=c[pos]+val; pos=pos+lowbit(pos); } } int getsum(int pos) { int res=0; while(pos>0) { res=res+c[pos]; pos=pos-lowbit(pos); } return res; } int get(int num) { int l=0,r=tot-1; while(l<=r) { int mid=(l+r)/2; if(lsh[mid]<=num) { if(lsh[mid]==num) return mid+1; else l=mid+1; } else r=mid-1; } } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { int li,ri; scanf("%d%d",&li,&ri); lsh[tot++]=li; lsh[tot++]=ri; p[i].x=li; p[i].y=ri; p[i].id=i; } sort(lsh,lsh+tot); for(int i=1;i<=n;i++) { p[i].x=get(p[i].x); p[i].y=get(p[i].y); } sort(p+1,p+1+n,cmp); memset(c,0,sizeof c); for(int i=1;i<=n;i++) update(p[i].y,1); for(int i=1;i<=n;i++) { if(p[i].x+1>p[i].y-1) p[i].ans=0; else p[i].ans=getsum(p[i].y-1)-getsum(p[i].x+1); update(p[i].y,-1); } sort(p+1,p+1+n,cmp2); for(int i=1;i<=n;i++) printf("%d\n",p[i].ans); return 0; }