poj 2481

来源:互联网 发布:淘宝达人联盟 编辑:程序博客网 时间:2024/05/18 02:32

给出 n条线段,要求 每条线段 被 几条 覆盖,起点和终点都相同不算覆盖。。

很明显的树状数组。。跑了 1000+ms

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define for if(0);else forconst int maxn=100005;struct In{int x,y;int index;}dat[maxn];int c[maxn];int ans[maxn];int lowbit(int x){return x&(-x);}void update(int i){while(i<=maxn){c[i]++;i+=lowbit(i);}}int getsum(int i){int sum=0;while(i>0){sum+=c[i];i-=lowbit(i);}return sum;}int cmp(In a,In b){if(a.x!=b.x)return a.x<b.x;return a.y>b.y;}int main(){int n;while(scanf("%d",&n)&&n){for(int i=0;i<n;i++){scanf("%d%d",&dat[i].x,&dat[i].y);dat[i].x+=2;dat[i].y+=2;//y应该从2开始,保证后面 y-1>=1dat[i].index=i;}sort(dat,dat+n,cmp);//按x从小到大排序,x相同按y从大到小排序,获得最大的 范围memset(c,0,sizeof(c));update(dat[0].y);ans[dat[0].index]=0;//第一条线段 肯定 没人可以覆盖它for(int i=1;i<n;i++){if(dat[i].x==dat[i-1].x&&dat[i].y==dat[i-1].y)ans[dat[i].index]=ans[dat[i-1].index];//两条线段相同 则 他们的覆盖次数也相同else {ans[dat[i].index]=i-getsum(dat[i].y-1);//判断1~y-1和sum 为多少,即比y小的有几个,i-sum 就是对应的值}update(dat[i].y);//将y加入}for(int i=0;i<n;i++)printf("%d%c",ans[i],i==n-1?'\n':' ');}}/*eg:804 63 60,update(6);11 33 60,update(6);21 4==》3 52-getsum(4)=2,update(5);34 54 53-getsum(4)=3,update(5);42 35 7...55 66 864 56 771 47 8*/


原创粉丝点击