poj 2352 Stars

树状数组第一题。水题。

 

虽然是看着别人的代码过的吧,不过确实对树状数组有了个了解。

 

树状数组的一系列操作都是logn的,所以在数据很大的情况很适用。

 

这题是,给你一系列点(按y递增,x递增排列),level[X] 指的是 不超过当前点的高度和不在当前点右边的点的个数为x 的这些点的个数。

 

读入一个点,判断它是哪个等级的,然后将这个等级的点的个数加一即可

 

#include <queue> #include <stack> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <iostream> #include <limits.h> #include <string.h> #include <algorithm> #define MAX 32010 using namespace std; int lev[MAX]; int c[MAX]; // 树状数组 int Lowbit(int x) { return x & (-x); } void Updata(int x) //插入一个 x 就要更新 x 的祖先们 { while( x < MAX ) { c[x]++; x += Lowbit(x); } } int Getsum(int x) // 求得 x 的等级 ,也就是 x 前面有多少个和x同列或者靠左的点 { // 因为输入的时候,y是递增的,所以不用考虑y int sum = 0; while( x > 0 ) { sum += c[x]; x -= Lowbit(x); // x 前面的一棵子树的根的下标 } return sum; } int main() { int n,x,y,i; while( ~scanf("%d",&n) ) { memset(lev,0,sizeof(lev)); memset(c,0,sizeof(c)); for(i=1; i<=n; i++) { scanf("%d%d",&x,&y); x++; lev[Getsum(x)]++; Updata(x); } for(i=0; i<n; i++) printf("%d/n",lev[i]); } return 0; }  

你可能感兴趣的:(c,2010)