hdu1541 Stars(树状数组+解释)
2016-04-28 08:35
411 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1541
题意:有n个星星,输入时是以从下到上,从左到右的方式输入(x,y)的值。每个星星左下方有多少个星星就评多少等级,求0~n-1个等级分别有多少个星星。
思路:树状数组入门题,第二次做。首先上博客,这篇写的很好,看完就懂了。树状数组主要用的是二进制思想,相比于普通数组在更新和求和上从O(n)优化到了O(n-1)。
本题要求的是每个星星左下方有多少个星星,因为后遍历的肯定是上方,所以只需求出左边有多少个星星。这样我们把每个星星量化为一个,求左边有多少星星就是求和。这里每组最多15000个星星,还有多组,普通数组耗时过多。这样就用到了树状数组。树状数组那个大牛解释的很好了,不过为了巩固还是要写些注释。
这里我把每个lowbit换成了组的说法。
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std;
typedef long long ll;
const int N = 32001;
int tree
;//从当前元素开始连续往左求lowbit(x)个数的和
int level
;//保存等级
int lowbit(int x)
{
return -x&x;
}
void add(int x)//更新
{
while(x < N)//临界值32001,代表某一项改变临界区内相应组的值也要改变
{
tree[x]+=1;//涉及到的组加一,代表多一个等级(类似于打表)
x+=lowbit(x);//去尾操作,变成下一个被涉及到的组
}
}
int sum(int x)
{
int rankk = 0;//星星的等级就相当于总和,每个星星左边有多少个星星,等级即为多少
while(x > 0)//说明还有组可加
{
rankk+=tree[x];//总星数加上本星星左方每组有多少星星
x-=lowbit(x);//用二分递减的规则使x变成下一组
}
return rankk;
}
int main()
{
// freopen("in.txt", "r", stdin);
int n, x, y;
while(~scanf("%d", &n))
{
memset(level, 0, sizeof(level));
memset(tree, 0, sizeof(tree));
for(int i = 1; i <= n; i++)
{
scanf("%d%d", &x, &y);
level[sum(++x)]++;
add(x);
}
for(int i = 0; i < n; i++)
printf("%d\n", level[i]);
}
return 0;
}
题意:有n个星星,输入时是以从下到上,从左到右的方式输入(x,y)的值。每个星星左下方有多少个星星就评多少等级,求0~n-1个等级分别有多少个星星。
思路:树状数组入门题,第二次做。首先上博客,这篇写的很好,看完就懂了。树状数组主要用的是二进制思想,相比于普通数组在更新和求和上从O(n)优化到了O(n-1)。
本题要求的是每个星星左下方有多少个星星,因为后遍历的肯定是上方,所以只需求出左边有多少个星星。这样我们把每个星星量化为一个,求左边有多少星星就是求和。这里每组最多15000个星星,还有多组,普通数组耗时过多。这样就用到了树状数组。树状数组那个大牛解释的很好了,不过为了巩固还是要写些注释。
这里我把每个lowbit换成了组的说法。
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <math.h>
using namespace std;
typedef long long ll;
const int N = 32001;
int tree
;//从当前元素开始连续往左求lowbit(x)个数的和
int level
;//保存等级
int lowbit(int x)
{
return -x&x;
}
void add(int x)//更新
{
while(x < N)//临界值32001,代表某一项改变临界区内相应组的值也要改变
{
tree[x]+=1;//涉及到的组加一,代表多一个等级(类似于打表)
x+=lowbit(x);//去尾操作,变成下一个被涉及到的组
}
}
int sum(int x)
{
int rankk = 0;//星星的等级就相当于总和,每个星星左边有多少个星星,等级即为多少
while(x > 0)//说明还有组可加
{
rankk+=tree[x];//总星数加上本星星左方每组有多少星星
x-=lowbit(x);//用二分递减的规则使x变成下一组
}
return rankk;
}
int main()
{
// freopen("in.txt", "r", stdin);
int n, x, y;
while(~scanf("%d", &n))
{
memset(level, 0, sizeof(level));
memset(tree, 0, sizeof(tree));
for(int i = 1; i <= n; i++)
{
scanf("%d%d", &x, &y);
level[sum(++x)]++;
add(x);
}
for(int i = 0; i < n; i++)
printf("%d\n", level[i]);
}
return 0;
}
相关文章推荐
- 【HDU 5366】The mook jong 详解
- 【HDU 2136】Largest prime factor 详细图解
- 【HDU 1568】Fibonacci 数学公式 详解
- HDU 1568
- HDU1290
- HDU1568(Fobonacci公式)
- HDU ACM Step 2.2.2 Joseph(约瑟夫环问题)
- HDU 1405
- HDU 1297
- hdu 1205
- hdu 2087
- hdu 1016
- HDU 4898 The Revenge of the Princess’ Knight ( 2014 Multi-University Training Contest 4 )
- HDU 5592 ZYB's Premutation 线段树(查找动态区间第K大)
- HDU 5240 Exam (好水的题)
- HDU5237 Base64 大模拟
- HDU 1000
- HDU 1001
- HDU 1016 Prime Ring Problem
- HDU 1017 A Mathematical Curiosity