poj 2352-Stars

来源:互联网 发布:美工设计助理骗局 编辑:程序博客网 时间:2024/05/29 03:36

链接:http://poj.org/problem?id=2352

因为题目给出的数据y是非递减的,所以y可以直接忽略掉,题目不是很难,比较适合练手,给出线段树和树状数组做的代码


线段树:

#include<stdio.h>#include<string.h>#define MAXN 32010int sum[15010];struct node{    int l,r;    int s;}t[4*MAXN];void construct(int l,int r,int p){    t[p].l=l;    t[p].r=r;    t[p].s=0;    if(l==r)        return ;    int m=(l+r)/2;    construct(l,m,p*2);    construct(m+1,r,p*2+1);}int query(int l,int r,int p){    if(t[p].l==l&&t[p].r==r)        return t[p].s;    int m=(t[p].l+t[p].r)/2;    if(r<=m)        return query(l,r,p*2);    else if(l>m)        return query(l,r,p*2+1);    else        return query(l,m,p*2)+query(m+1,r,p*2+1);}void insert(int x,int p){    if(t[p].l==t[p].r&&t[p].l==x)    {        t[p].s++;        return ;    }    int m=(t[p].l+t[p].r)/2;    if(x<=m)        insert(x,p*2);    else        insert(x,p*2+1);    t[p].s=t[p*2].s+t[p*2+1].s;}int main(){    int n,i,x,y;    while(scanf("%d",&n)!=EOF)    {        memset(t,0,sizeof(t));        memset(sum,0,sizeof(sum));        construct(0,32001,1);        for(i=0;i<n;i++)        {            scanf("%d%d",&x,&y);            insert(x,1);            sum[query(0,x,1)-1]++;        }        for(i=0;i<n;i++)            printf("%d\n",sum[i]);    }    return 0;}

树状数组:

#include<stdio.h>#include<string.h>#define MAXN 15010int ans[MAXN],c[MAXN*2+3000];int lowbit(int x){return x&(-x);}int sum(int i){int s=0;while(i>0){s+=c[i];i-=lowbit(i);}return s;}void add(int i,int val){while(i<=32001)//需要一层一层地往上更新数组{c[i]+=val;i+=lowbit(i);}}int main(){int n,x,y,i;while(scanf("%d",&n)!=EOF){for(i=0;i<n;i++){scanf("%d%d",&x,&y);ans[sum(x+1)]++;add(x+1,1);}for(i=0;i<n;i++)printf("%d\n",ans[i]);}return 0;}