链接:http://poj.org/problem?id=2352
因为题目给出的数据y是非递减的,所以y可以直接忽略掉,题目不是很难,比较适合练手,给出线段树和树状数组做的代码
线段树:
#include<stdio.h>
#include<string.h>
#define MAXN 32010
int 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 15010
int 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;
}