afterward

导航

 

不懂树状数组时什么意思,找了个简单的树状数组做!

 

View Code
#include <iostream>
using namespace std;
#define N 32001
int sum[N+1];
//算这个^k有一个快捷的办法,定义一个函数如下即可
//利用机器补码的特点,这个函数可以改得更方便
int lowbit(int k)
{
    return k&(-k);
}
//如果要把a[i]增加v,可以通过调用如下函数实现
void add(int i,int v)
{
    while(i<=N)
    {
        sum[i]+=v;
        cout<<"i:"<<i<<"  >>"<<sum[i]<<endl;
        i+=lowbit(i);

    }
}
//如果要统计a[1]到a[i]之间的和,可以通过调用如下函数实现
int getSum(int i)
{
    int s=0;
    while(i>0)
    {
        s+=sum[i];
        cout<<"--i:"<<i<<" --"<<s<<endl;
        i-=lowbit(i);
    }
    return s;
}
int main()
{
    int n,i,x,y;
    cin>>n;
    int*result=new int[n];
//初始化数组
    for(i=0; i<n; i++)
    {
        result[i]=0;
    }
    for(i=1; i<=N; i++)
    {
        sum[i]=0;
    }
    for(i=0; i<n; i++)
    {
        cin>>x>>y;
        int t=getSum(x+1);
        result[t]++;//统计
        cout<<t<<" "<<result[t]<<endl;
        add((x+1),1);//更新sum[i]的值
    }
    for(i=0; i<n; i++)
    {
        cout<<result[i]<<endl;
    }
    return 1;
}

 

 


只要有方法,也可以不用上面的方法。

 

 

View Code
#include<iostream>
#include<stdio.h>
using namespace std;
struct node{
 int aa,bb,flag,left,right;
};
node b[100000];
int a[50000][3],f[50000],c[50000],tot;
void build(int x,int y)
{
 int now;
 tot++;
 now=tot;
 b[now].aa=x;
 b[now].bb=y;
 b[now].flag=0;
 if (x!=y)
 {
  b[now].left=tot+1;
  build(x,(x+y)/2);
     b[now].right=tot+1;
  build((x+y)/2+1,y);
 }
}
void insert(int x,int y)
{
 int mid;
 if ((b[x].aa==b[x].bb)&&(b[x].aa==y))
 {
  b[x].flag++;
 }
 else
 {
  mid=(b[x].aa+b[x].bb)/2;
  if (y<=mid) insert(b[x].left,y);
  if (y>mid) insert(b[x].right,y);
  b[x].flag=b[b[x].left].flag+b[b[x].right].flag;
 }
}
void find(int x,int y,int z)
{
 int mid;
 if (b[x].aa==b[x].bb) c[z]+=b[x].flag;
 else
 {
  mid=(b[x].aa+b[x].bb)/2;
  if (y<=mid) find(b[x].left,y,z);
  if (y>mid) {c[z]+=b[b[x].left].flag;find(b[x].right,y,z);}
 }
}
int main()
{
 int n,max,i;
 scanf("%d",&n);
 max=0;
 for(i=1;i<=n;i++)
 {
  scanf("%d%d",&a[i][0],&a[i][1]);
  if (a[i][0]>max) max=a[i][0];
 }
 tot=0;
 build(0,max);
 for(i=1;i<=n;i++)
 {
  c[i]=0;
  find(1,a[i][0],i);
  insert(1,a[i][0]);
 }
 for(i=0;i<=n;i++)
  f[i]=0;
 for(i=1;i<=n;i++)
  f[c[i]]++;
 for(i=0;i<=n-1;i++)
  printf("%d\n",f[i]);
 return 0;
}

 

 

 

 

【树状数组】数星星(POJ2352 star)

Time Limit:1000MS  Memory Limit:65536K

Total Submit:23 Accepted:16

Description

天文学家经常观察星象图。星象图中用平面上的点来表示一颗星星,每一颗星星都有一个笛卡尔坐标。设定星星的等级为其左下角星星的总数。天文学家们想知道星星等级的分布情况。

比如上图,5号星星的等级为3(其左下角有编号为1、2、4的星星共三颗)。2号星星和4号星星的等级为1。在上图中只

有一颗星星等级为0,两颗星星等级为1,一颗星星等级为2,一颗星星等级为3。

给定一个星象图,请你写一个程序计算各个等级的星星数目。

Input

输入的第一行包含星星的总数N (1<=N<=15000)。接下来N行,描述星星的坐标(X,Y)(X和Y用空格分开,

0<=X,Y<=32000)。星象图中的每个点处最多只有一颗星星。所有星星按Y坐标升序排列。Y坐标相等的星星按X坐标升序排列。

Output

输出包含N行,每行一个整数。第一行包含等级0的星星数目,第二行包含等级1的星星数目,依此类推,最后一行包含

等级为N-1的星星数目。

Sample Input

5

1 1

5 1

7 1

3 3

5 5

Sample Output

1

2

1

1

0

posted on 2012-08-07 11:04  afterward  阅读(451)  评论(0编辑  收藏  举报