标签:
求每个集合是其他多少个集合的真子集
树状数组 + 离散化 依据左端点将线段变成点,单点更新,求区间和。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct node{ int l,r; int index; }nod[100010]; int n; int ans[100010] ,tree[100010]; int y[1000010] ; bool cmp(node a,node b) { if(a.r == b.r){ return a.l<b.l ; } return a.r>b.r ; } inline int lowbit(int x){ return x&(x^(x-1)) ; } void add(int x,int value) { for(int i=x;i<=n;i+=lowbit(i)){ tree[i]+=value ; } } int sum(int x) { int temp=0; for(int i=x;i>0;i-=lowbit(i)){ temp+=tree[i] ; } return temp; } int main() { while(~scanf("%d",&n) && n!=0){ int cnt=1; for(int i=1;i<=n;i++){ scanf("%d%d",&nod[i].l,&nod[i].r); nod[i].index=i; y[cnt++]=nod[i].l,y[cnt++]=nod[i].r; } sort(y+1,y+cnt+1) ; int all=unique(y+1,y+cnt+1)-y; for(int i=1;i<=n;i++){ int a=lower_bound(y+1,y+all+1,nod[i].l)-y; nod[i].l=a; a=lower_bound(y+1,y+all+1,nod[i].r)-y; nod[i].r=a; } sort(nod+1,nod+n+1,cmp); memset(tree,0,sizeof tree) ; memset(ans,0,sizeof(ans)); add(nod[1].l,1); node pre=nod[1] ; for(int i=2 ;i<=n;i++){ if(nod[i].l==pre.l && nod[i].r == pre.r){ ans[nod[i].index]=ans[nod[i-1].index]; } else{ ans[nod[i].index]=sum(nod[i].l); } add(nod[i].l,1); pre=nod[i] ; } printf("%d",ans[1]); for(int i=2;i<=n;i++){ printf(" %d",ans[i]); } printf("\n") ; } return 0; }
标签:
原文地址:http://www.cnblogs.com/Scale-the-heights/p/4707369.html