POJ-2352 && hdu-1541 Stars---树状数组的运用
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1541
题目大意 :
在坐标上有n个星星,如果某个星星坐标为(x, y), 它的左下位置为:(x0,y0),x0<=x 且y0<=y。如果左下位置有a个星星,就表示这个星星属于level x
按照y递增,如果y相同则x递增的顺序给出n个星星,求出所有level水平的数量。
解题思路:
题目已将排好序输入,所以可以不用排序
在y递增的时候,树状数组来维护x坐标,每次输入一个坐标的时候,求出当前有多少个x小于等于当前的x,那就是该点的等级,所以直接用树状数组求出小于等于x的数目,求出该点等级之后,再把这点的x坐标加入树状数组。
为什么求出当前有多少个x小于等于当前的x,那就是该点的等级呢
因为题目输入的y是递增的,y相等的时候x递增,这样的话每次放入一个点,前面所有的点的y都是小于等于该点的y,所以只要数一下x就可以了
注意:
树状数组的上限是x坐标的上限,不是n。这一点很重要
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<string> 6 #include<cmath> 7 #include<set> 8 #include<queue> 9 #include<map> 10 #include<stack> 11 #include<vector> 12 #include<list> 13 #include<deque> 14 #include<sstream> 15 #include<cctype> 16 #define REP(i, n) for(int i = 0; i < (n); i++) 17 #define FOR(i, s, t) for(int i = (s); i < (t); i++) 18 using namespace std; 19 typedef long long ll; 20 typedef unsigned long long ull; 21 const int maxn = 33333; 22 const double eps = 1e-10; 23 const int INF = 1 << 30; 24 const int dir[4][2] = {1,0,0,1,0,-1,-1,0}; 25 const double pi = 3.1415926535898; 26 int n; 27 int d[maxn], ans[15100]; 28 int lowbit(int x) 29 { 30 return (x & -x); 31 } 32 int sum(int x) 33 { 34 int tot = 0; 35 while(x > 0) 36 { 37 tot += d[x]; 38 x -= lowbit(x); 39 } 40 return tot; 41 } 42 void add(int x, int t) 43 { 44 while(x <= maxn)///这里maxn是d数组的上限 45 { 46 d[x] += t; 47 x += lowbit(x); 48 } 49 } 50 int main() 51 { 52 while(cin >> n) 53 { 54 int x, y; 55 memset(d, 0, sizeof(d)); 56 memset(ans, 0, sizeof(ans)); 57 FOR(i, 0, n) 58 { 59 cin >> x >> y; 60 x++;//x不可以为0,如果为0会使得树状数组进入无限循环而超时 61 ans[sum(x)]++; 62 add(x, 1); 63 } 64 FOR(i, 0, n)cout << ans[i] << endl; 65 } 66 }
越努力,越幸运