poj 2352 线段树

来源:互联网 发布:k svd字典训练算法 编辑:程序博客网 时间:2024/04/30 18:51

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N=15005;
const int M=32005;

struct node
{
  int x,y;
}star[N];

struct T
{
  int l,r;
  int sum;
}tree[4*M];

int num[M];

void Creat(int l,int r,int p)
{
  tree[p].l=l;
  tree[p].r=r;
  tree[p].sum=0;
  if(tree[p].l==tree[p].r)
    return;
  int m=tree[p].l+tree[p].r>>1;
  Creat(l,m,p<<1);
  Creat(m+1,r,(p<<1)+1);
}

void addi(int a,int p)
{
  tree[p].sum++;
  if(tree[p].l==tree[p].r)
    return;
  int m=tree[p].l+tree[p].r>>1;
  if(a<=m)
    addi(a,p<<1);
  else
    addi(a,(p<<1)+1);
}

int get_sum(int l,int r,int p)
{
  if(tree[p].l==l&&tree[p].r==r)
    return tree[p].sum;
  int m=tree[p].l+tree[p].r>>1;
  if(l>m)
    return get_sum(l,r,(p<<1)+1);
  if(r<=m)
    return get_sum(l,r,p<<1);
  return get_sum(l,m,p<<1)+get_sum(m+1,r,(p<<1)+1);
}

int main()
{
  int i,n;
  while(scanf("%d",&n)!=EOF)
  {
    memset(num,0,sizeof(num));
    int max=-1;
    for(i=0;i<n;i++)
    {
      scanf("%d%d",&star[i].x,&star[i].y);
      if(max<star[i].x)
        max=star[i].x;//找到星星中x的最大坐标
    }
    Creat(0,max,1);//建立一个从0到x的二叉树
    for(i=0;i<n;i++)
    {
      num[get_sum(0,star[i].x,1)]++;//每次查询在这个星星左边的星星的个数
      addi(star[i].x,1);//顺次向后查询的过程中,更改节点的值
    }
    for(i=0;i<n;i++)
      printf("%d/n",num[i]);
  }
 
  return 0;
}

原创粉丝点击