POJ 2352 star (树状数组)


Language:
Default

Stars

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 35318   Accepted: 15326

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

Ural Collegiate Programming Contest 1999

这一个题我发现了 当x=0时,x+lowbit(x)=0;所以必须x++,否则update(0)就会死循环

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>

#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)

#define eps 1e-8
typedef __int64 ll;

#define fre(i,a,b)  for(i = a; i <b; i++)
#define free(i,b,a) for(i = b; i >= a;i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define ssf(n)      scanf("%s", n)
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define bug         pf("Hi\n")

using namespace std;

#define INF 0x3f3f3f3f
#define N 32005

struct stud{
 int x,y;
 bool operator <(const stud b) const
 {
     if(x==b.x)
       return y<b.y;
     return x<b.x;
 }
}f[15005];

int ans[N];
int c[N];
int ma,n;

inline int lowbit(int x)
{
    return x&(-x);
}

void update(int x)
{
    while(x<=ma)
    {
        c[x]++;
        x+=lowbit(x);
    }
}
int Sum(int x)
{
    int s=0;
    while(x)
    {
        s+=c[x];
        x-=lowbit(x);
    }
   return s;
}

int main()
{
    int i,j;

    sf(n);
    mem(ans,0);
    ma=-1;
    for(i=0;i<n;i++)
    {
         sff(f[i].x,f[i].y);
         f[i].y++;
         ma=max(ma,f[i].y);
    }

    sort(f,f+n);
    mem(c,0);

    for(i=0;i<n;i++)
    {
        int t=Sum(f[i].y);
        ans[t]++;
        update(f[i].y);
    }
    for(i=0;i<n;i++)
        pf("%d\n",ans[i]);

    return 0;

}
时间: 2024-10-11 09:19:31

POJ 2352 star (树状数组)的相关文章

POJ 2352 Stars(树状数组 or 线段树)

链接: http://poj.org/problem?id=2352 题目大意: 在坐标上有n个星星,如果某个星星坐标为(x, y), 它的左下位置为:(x0,y0),x0<=x 且y0<=y.如果左下位置有a个星星,就表示这个星星属于level x 按照y递增,如果y相同则x递增的顺序给出n个星星,求出所有level水平的数量. 思路: 由于输入的顺序,对于第i颗星星,它的等级是之前输入的星星中,横坐标x小于等于i星横坐标的那些星星的总数量(前面的y一定比后面的y小). 所以是查询+更新操作

POJ 2481 Cows &amp;&amp; POJ 2352 Stars(树状数组妙用)

题目链接:POJ 2481 Cows POJ 2352 Stars 发现这两个题目都跟求逆序数有着异曲同工之妙,通过向树状数组中插入点的位置,赋值为1,或者++,然后通过求和来判断比当前 点 "小" 的有多少点. Cows需要自己排序, Stars题目已经给排好序. POJ 2352 Stars 题目大意为在二维坐标上给出一些星星的坐标,求某一个星星左方,下方,左下方的星星个数.题目已经把星星按照Y坐标从小到大,X从小到大排序.因此,在每次对一个星星进行统计时,之前出现过的星星,只要X

POJ 2352 【树状数组】

题意: 给了很多星星的坐标,星星的特征值是不比他自己本身高而且不在它右边的星星数. 给定的输入数据是按照y升序排序的,y相同的情况下按照x排列,x和y都是介于0和32000之间的整数.每个坐标最多有一个星星. 思路: 这题给的输入数据很祥和,间接提示思路了. 用x作为树状数组的区间,然后按照输入的顺序不断查找在包括自己的位置以及左边的星星数. 细节是x可能是0,这是树状数组不能接受的,需要对输入的x数据进行加一操作. 从这题可以看出树状数组最直白的作用就是求从1开始到某个点的某个区间的数量. #

POJ 2309 BST 树状数组基本操作

Description Consider an infinite full binary search tree (see the figure below), the numbers in the nodes are 1, 2, 3, .... In a subtree whose root node is X, we can get the minimum number in this subtree by repeating going down the left node until t

Poj 2299 Ultra-QuickSort 树状数组 解法

本题的树状数组稍微有点特点,就是需要所谓的离散化一下,开始听这个名称好像很神秘的,不过其实很简单. 就是把一个数组arr的值,其中的值是不连续的,变成一组连续的值,因为这样他们的顺序是不变的,所以,不影响结果. 例如:9 1 0 5 4 ->变为:5 2 1 4 3看出他们的相对位置不变的. 9和5为最大值在第一个位置,1和2为第二大的值在第二个位置,0和1在第一个位置等,看出对应顺序了吗? 对,就是这么简单的方法, 就叫做离散化. 如果你对counting sort熟悉的话,那么这样的思想理解

POJ 2481 Cows(树状数组)

Description Farmer John's cows have discovered that the clover growing along the ridge of the hill (which we can think of as a one-dimensional number line) in his field is particularly good. Farmer John has N cows (we number the cows from 1 to N). Ea

POJ 2481 COWS(树状数组)

题目大意: 说给你n个线段的,告诉你每个线段的起始点S_i,和终止点E_i, 问这n条线段里有多少线段是相互包含的,如果两个端点重合不算包含. 解题思路: 用树状数组搞就可以了,这道题是star的变形题,star是让我们求出有多个星星在这个星星的左下角,而这道题是让我们求出有多少个星星在这个星星的左上角. 这样分析,对于(S_i,E_i)我们把他封装成为一个点的坐标,那么(S_j,E_j)同样也可以被封装成为一个点的坐标,而题目中说的S_i<S_j&&E_j<E_i&&

poj 2481 Cows 树状数组解法,详细解析。

Cows Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13445   Accepted: 4448 Description Farmer John's cows have discovered that the clover growing along the ridge of the hill (which we can think of as a one-dimensional number line) in hi

POJ 2299 Ultra-QuickSort(树状数组 + 离散)

链接:http://poj.org/problem?id=2299 题意:给出N个数组成的数列A(0 <= A[i] <= 999,999,999),求该数列逆序对的数量. 分析:题目所谓的排序过程其实就是一个冒泡排序的过程.在这里,我们需要知道,冒泡排序所需交换的次数等于该序列逆序对的数量(证明略).这是这道题的一个切入点. 树状数组可以很方便地求出数列的前缀和,对于一个数x,我们使树状数组上第x个元素的值赋为1,这时调用Sum(x)就可以得到一个从第1项到第x项的前缀和.这意味着我们可以通

POJ 2299 Ultra-QuickSort (树状数组or 归并排序分治求逆序对数)

题目大意就是说帮你给一些(n个)乱序的数,让你求冒泡排序需要交换数的次数(n<=500000) 显然不能直接模拟冒泡排序,其实交换的次数就是序列的逆序对数. 由于数据范围是 0 ≤ a[i] ≤ 999,999,999所以先要离散化,然后用合适的数据结果求出逆序 可以用线段树一步一步添加a[i],每添加前查询前面添加比它的大的有多少个就可以了. 也可用树状数组,由于树状数组求的是(1...x)的数量和所以每次添加前查询i-sum(a[i])即可 树状数组: //5620K 688MS #incl