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 }
原文地址:https://www.cnblogs.com/fzl194/p/8928165.html