树状数组(2)
来源:互联网 发布:事业单位域名注册 编辑:程序博客网 时间:2024/05/16 10:35
一维树状数组的应用
poj 2352 stars
题意:在整数坐标0<=x,y<=32000上有很多星星
每颗星的level(级别)值 等于 不比它高不比它右的星星数目
给出每颗星星的坐标。求每个level的星星数目。
学过的同志们一定会会心地一笑了,没有做过的同志们肯定也懵逼了(内心独白:what?这跟树状数组有何关系?)
其实大家
算法分析:
好像要所有数据读入之后才一个个问,其实不然,我们可以采取一边读数据一边统计的方法
(注意了,输入格式已经给出:星星按 Y 的升序给出,Y 相等则按 X 的升序给出)。
也是就是当前的第i个星星读入坐标的时候其实它的级别已经确定了,因为后面的星星不会让星星i升级的,
(因为星星是按Y升序给出的,所以后面的星星不会比当前星星i低,最多同高,但因为同高的星星是从左到右给出的,所以后面的星星不会在当前星星i的左边。)
所以我们只需要 关注 每颗星星的x坐标,统计 1~x[i]有多少个值出现过,出现过的点为1,那么我们就可以统计了。
代码:
#include <cstdio>#include <cstring>using namespace std;int c[32010],l[32010],n;int lowbit(int x){ return x&-x;}void add(int x,int y){ while (x<=32005) { c[x]+=y; x+=lowbit(x); }}int getsum(int x){ int s=0; while (x>=1) { s+=c[x]; x-=lowbit(x); } return s;}int main(){ int x,y; while (scanf("%d",&n)!=EOF) { memset(c,0,sizeof(c)); memset(l,0,sizeof(l)); for (int i=1;i<=n;i++) { scanf("%d%d",&x,&y); add(x+1,1); l[getsum(x+1)]++; } for (int i=1;i<=n;i++) printf("%d\n",l[i]); }}
stars的拓展:
poj2481 cows
看到这道题,做过的同志们肯定又要偷笑了,没看过的同志们又接着懵逼了
题意:
一条线上有很多不同长度的线段【s,e】,代表了不同牛的领域范围。如果Si <= Sj 并且 Ej <= Ei 并且 Ei - Si > Ej - Sj 就说明母牛i比母牛j强壮。对于每一头牛,有多少头牛比他强壮?
算法分析:
我们可以把这一条线段扩大成一片草地(类似平面直角坐标系的东东),将每头母牛的领域范围线段【s,e】变为一个在平面直角坐标系上的点【s,e】。画一画图,是不是和上面的stars很像咧?只需要变动一下(注意:stars是求他左下方有多少个点,而这一题则是求他的左上方有多少个点)。
值得提醒一下的是:这一题的数据是无序给出的,我们需要预先排序。
- hust1433-树状数组-2
- hdu4000-树状数组-2
- 树状数组(2)
- 树状数组(2)
- 树状数组(2)
- 树状数组(2)
- 【模板】树状数组 2
- 树状数组模板2
- 【模板】树状数组2
- 23th 【树状数组】树状数组1&&2
- [caioj 树状数组2(破坏公路)]---树状数组
- 【洛谷3368】树状数组 2 树状数组+差分
- 洛谷3368树状数组2
- c++树状数组2模板
- 树状数组
- 树状数组
- 树状数组
- 树状数组
- 垂悬指针问题
- 省市区SQL
- 单例模式与多线程
- Gauge中执行测试的常用命令
- c++ 逆向存放二维数组
- 树状数组(2)
- File文件的属性获取
- 1--WM虚拟机双网卡接入主机双网卡设置
- 2012国家集训队Round 1 day1 攻占黄金乡
- Spark基本工作原理
- IIS应用程序池添加ASP.NET v4.0
- 数据结构(C++)——双循环链表
- 每天10个前端知识点:js组成篇
- 简单Python爬虫实例