您的位置:首页 > 其它

poj 2481 树状数组

2015-04-20 17:04 162 查看
题目大意:给你很多线段的头S和尾E,问每一条线段中包含了多少个线段,(S和E相同不计在内)

变成坐标系上的点后求每个点左上角的点的个数

按y从大到小插入结点

3
1 2
0 3
3 4
0

1 0 0

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
#define MOD 1000000007
const int INF=0x3f3f3f3f;
const double eps=1e-5;
#define cl(a) memset(a,0,sizeof(a))
#define ts printf("*****\n");
int n,m,tt;
const int MAXN=100005;
int c[MAXN],val[MAXN];
int lowbit(int x)
{
return x&(-x);
}
void add(int i,int val)
{
while(i<=n)
{
c[i]+=val;
i+=lowbit(i);
}
}
int sum(int i)
{
int s=0;
while(i>0)
{
s+=c[i];
i-=lowbit(i);
}
return s;
}
struct node
{
int x,y,id;
void in(int i)
{
scanf("%d%d",&x,&y);
x++,y++;
id=i;
}
}a[MAXN];
bool cmp(node a,node b)
{
if(a.y==b.y)    return a.x<b.x;
return a.y>b.y;
}
int main()
{
int i,j;
#ifndef ONLINE_JUDGE
freopen("1.in","r",stdin);
#endif
while(scanf("%d",&n)!=EOF&&n!=0)
{
cl(val);
cl(c);
cl(a);
for(i=0;i<n;i++)
{
a[i].in(i);
}
sort(a,a+n,cmp);
val[a[0].id]=0;
add(a[0].x,1);
for(i=1;i<n;i++)
{
if(a[i].x==a[i-1].x&&a[i].y==a[i-1].y)  val[a[i].id]=val[a[i-1].id];    //区间完全重合
else
{
val[a[i].id]=sum(a[i].x);
}
add(a[i].x,1);
}
int k=0;
for(i=0;i<n;i++)
{
if(k++) printf(" ");
printf("%d",val[i]);
}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: