树状数组(模板)

来源:互联网 发布:生产线显示屏 网络 编辑:程序博客网 时间:2024/06/05 11:26

照例先来一道模板题

poj题号:2352
Stars
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 49475 Accepted: 21340
Description

Astronomers often examine star maps where stars are represented by points on a plane and each star has Cartesian coordinates. Let the level of a star be an amount of the stars that are not higher and not to the right of the given star. Astronomers want to know the distribution of the levels of the stars.

For example, look at the map shown on the figure above. Level of the star number 5 is equal to 3 (it’s formed by three stars with a numbers 1, 2 and 4). And the levels of the stars numbered by 2 and 4 are 1. At this map there are only one star of the level 0, two stars of the level 1, one star of the level 2, and one star of the level 3.

You are to write a program that will count the amounts of the stars of each level on a given map.
Input

The first line of the input file contains a number of stars N (1<=N<=15000). The following N lines describe coordinates of stars (two integers X and Y per line separated by a space, 0<=X,Y<=32000). There can be only one star at one point of the plane. Stars are listed in ascending order of Y coordinate. Stars with equal Y coordinates are listed in ascending order of X coordinate.
Output

The output should contain N lines, one number per line. The first line contains amount of stars of the level 0, the second does amount of stars of the level 1 and so on, the last line contains amount of stars of the level N-1.
Sample Input

5
1 1
5 1
7 1
3 3
5 5
Sample Output

1
2
1
1
0
Hint

This problem has huge input data,use scanf() instead of cin to read data to avoid time limit exceed.
Source

什么?看不懂英语? 来来来,变成中文题面再看一次

.
.
.
题目描述:天文学家时常调查星图,星图在一个平面上表示出所有星星,而且每个星星都有笛卡尔坐标。星星的级别是不在它上面且不在它右面的星星的总数。 天文学家想知道每个星星的级别。

这里写图片描述
举例来说,看上面的图。 5号星星的级别是3(由 1,2 和 4 号而得)。2 点和 4 号星星的级别是 1. 在这个图里只有一个级别为 0 的星星,两个级别为 1 的星星,一个级别为 2 的星星和一个级别为 3 的星星。你的任务是计算每个级别的星星总数

Input
第一行包含一个数 N (1<=N<=15000)。一下 N 行描述相应的星星(每行两个用空格隔开的整数 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

就不进行分析了(我有另外写一篇讲解这个的,地质:http://blog.csdn.net/ojzha/article/details/75459499),在这只是照例上个模板题而已

#include<iostream>#include<cstring>#define LL long long #define MAXN 33000LL c[10000010],ans[10000010],n,x,tot=0,y,h;using namespace std;LL lowbit(LL x){    return x&(-x);}void update (LL x){    while (x<=MAXN)    {        c[x]+=1;        x+=lowbit(x);    }}LL getsum(LL x){    LL sum=0;    while(x>=1)    {        sum+=c[x];        x-=lowbit(x);    }    return sum;}int main(){    cin>>n;    for(int i=1;i<=n;i++)    {        cin>>x>>y;        h=getsum(x+1);        ans[h]++;        update(x+1,1);    }    for(LL i=0;i<=n-1;i++)    {        cout<<ans[i]<<endl;    }    return 0;}

.
.
.
好了,接下来是总结的树状数组的模板:

int MAXN//一个最大的值,一般是数字的个数 int c[10000010],n,x,tot=0,y,h;//c为树状数组 int lowbit(int x)//取位 {    return x&(-x);}void update (int x,int value)//更新 {    while (x<=MAXN)    {        c[x]+=value;        x+=lowbit(x);    }}int getsum(int x)//求和 {    int sum=0;    while(x>=1)    {        sum+=c[x];        x-=lowbit(x);    }    return sum;}