POJ 2352 树状数组
学习自:链接以及百度百科
以及:https://www.bilibili.com/video/av18735440?from=search&seid=363548948825132979
理解树状数组


概念
假设数组a[1..n],那么查询a[1]+...+a[n]的时间是log级别的,而且是一个在线的数据结构,支持随时修改某个元素的值,复杂度也为log级别。
观察这棵树,容易发现:
C1 = A1
C2 = A1 + A2
C3 = A3C4 = A1 + A2 + A3 + A4C5 = A5C6 = A5 + A6C7 = A7C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8......C16 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 + A9 + A10 + A11 + A12 + A13 + A14 + A15 + A16这里有一个有趣的性质:设节点编号为x,那么这个节点管辖的区间为2^k(其中k为x二进制末尾0的个数)个元素。因为这个区间最后一个元素必然为Ax,所以很明显:Cn = A(n – 2^k + 1) + ... + An算这个2^k有一个快捷的办法,定义一个函数如下即可:int lowerbit(int x){
return x&(x^(x–1));
}利用机器补码特性,也可以写成:int lowerbit(int x){
return x&-x;
}当想要查询一个SUM(n)(求a[n]的和),可以依据如下算法即可:step1: 令sum = 0,转第二步;step2: 假如n <= 0,算法结束,返回sum值,否则sum = sum + Cn,转第三步;step3: 令n = n – lowbit(n),转第二步。可以看出,这个算法就是将这一个个区间的和全部加起来,为什么是效率是log(n)的呢?以下给出证明:n = n – lowbit(n)这一步实际上等价于将n的二进制的最后一个1减去。而n的二进制里最多有log(n)个1,所以查询效率是log(n)的。那么修改呢,修改一个节点,必须修改其所有祖先,最坏情况下为修改第一个元素,最多有log(n)的祖先。所以修改算法如下(给某个结点i加上x):step1: 当i > n时,算法结束,否则转第二步;step2: Ci = Ci + x, i = i + lowbit(i)转第一步。i = i +lowbit(i)这个过程实际上也只是一个把末尾1补为0的过程。对于数组求和来说树状数组简直太快了!注:求lowbit(x)的建议公式:lowbit(x):=x and -x;或lowbit(x):=x and (x xor (x - 1));lowbit(x)即为2^k的值。

void add(int k,int num) {
while(k<=n) {
tree[k]+=num;
k+=k&-k;
}
}

【题目链接】
Stars
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 45080 | Accepted: 19567 |
- Description

For example, look at the map shown on the figure above. Level of the star number 5 is equal to 3 (it's formed by three stars with a numbers 1, 2 and 4). And the levels of the stars numbered by 2 and 4 are 1. At this map there are only one star of the level 0, two stars of the level 1, one star of the level 2, and one star of the level 3.
You are to write a program that will count the amounts of the stars of each level on a given map.
- Input
- Output
Sample Input
5
1 1
5 1
7 1
3 3
5 5
Sample Output
1
2
1
1
0
- Hint
【题意】
就是求每个小星星左小角的星星的个数。坐标按照Y升序,Y相同X升序的顺序给出 由于y轴已经排好序,可以按照x坐标建立一维树状数组。
#include <stdio.h>
#include <string.h>
const int MAXN=;
const int MINN=;
int tree[MAXN];//下标为横坐标
int level[MINN];//下标为等级数
/*int lowerbit(int x)
{
return x&-x;
}*/
void add(int k,int num)
{
while(k<=MAXN)
{
tree[k]+=num;
k+=k&-k;
}
}
int read(int k)//1~k的区间和
{
int sum=;
while(k)
{
sum+=tree[k];
k-=k&-k;
}
return sum;
}
int main()
{
int n,x,y,i;
memset(tree,,sizeof(tree));
memset(level,,sizeof(level));
while(scanf("%d",&n)!=EOF)
{
for(i=;i<=n;i++)
{
scanf("%d%d",&x,&y);
int temp=read(x+);//加入x+1,是为了避免0,X是可能为0的
level[temp]++;
add(x+,);
}
for(i=;i<n;i++)
printf("%d\n",level[i]);
}
return ;
}
POJ 2352 树状数组的更多相关文章
- POJ 2352Stars 树状数组
Stars Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 42898 Accepted: 18664 Descripti ...
- POJ 3321 树状数组(+dfs+重新建树)
Apple Tree Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 27092 Accepted: 8033 Descr ...
- poj 2299 树状数组求逆序数+离散化
http://poj.org/problem?id=2299 最初做离散化的时候没太确定可是写完发现对的---由于后缀数组学的时候,,这样的思维习惯了吧 1.初始化as[i]=i:对as数组依照num ...
- poj 3928 树状数组
题目中只n个人,每个人有一个ID和一个技能值,一场比赛需要两个选手和一个裁判,只有当裁判的ID和技能值都在两个选手之间的时候才能进行一场比赛,现在问一共能组织多少场比赛. 由于排完序之后,先插入的一定 ...
- POJ 2299 树状数组+离散化求逆序对
给出一个序列 相邻的两个数可以进行交换 问最少交换多少次可以让他变成递增序列 每个数都是独一无二的 其实就是问冒泡往后 最多多少次 但是按普通冒泡记录次数一定会超时 冒泡记录次数的本质是每个数的逆序数 ...
- poj 2299 树状数组求逆序对数+离散化
Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 54883 Accepted: 20184 ...
- poj 2182 树状数组
这题对于O(n^2)的算法有很多,我这随便贴一个烂的,跑了375ms. #include<iostream> #include<algorithm> using namespa ...
- POJ 2299树状数组求逆序对
求逆序对最常用的方法就是树状数组了,确实,树状数组是非常优秀的一种算法.在做POJ2299时,接触到了这个算法,理解起来还是有一定难度的,那么下面我就总结一下思路: 首先:因为题目中a[i]可以到99 ...
- MooFest POJ - 1990 (树状数组)
Every year, Farmer John's N (1 <= N <= 20,000) cows attend "MooFest",a social gather ...
随机推荐
- Jmeter(三十八)while控制器实现ssh三次重连
在jmeter中,可以使用SSH协议连接主机进行相关操作, 步骤如下 首先添加一个ssh command 我们的测试交流群:317765580 在command中填写远程连接的必要信息 结果树中可以 ...
- 浅谈一类无关序列有前缀和性质的统计问题的离线解法 BZOJ3626
每次询问[l,r]区间,但所有信息是按另一种序列给出的,因此无法使用区间数据结构做这种题.将每个询问改为[1,x],考虑离线,则从1~n依次修改并查询即可. BZOJ3626 给定一颗树,每次询问给定 ...
- PHP实用代码片段(三)
1. 目录清单 使用下面的 PHP 代码片段可以在一个目录中列出所有文件和文件夹. function list_files($dir) { if(is_dir($dir)) { if($handle ...
- SoftWater——SDN+UnderWater系列论文一
---- SoftWater: Software-defined networking for next-generation underwater communication systems 来源: ...
- PS制作动感酷炫水人街舞照
一.打开原图素材,用钢笔工具把人物从图中扣取出来,新建一个812 * 1024像素的文档,把抠出的人物拖进来,过程如下图. 二.用你习惯的修图工具把人物的手.脸部.腰部.袜子通通修掉.再补回衣服在透视 ...
- MyBatis模糊查询不报错但查不出数据的一种解决方案
今天在用MyBatis写一个模糊查询的时候,程序没有报错,但查不出来数据,随即做了一个测试,部分代码如下: @Test public void findByNameTest() throws IOEx ...
- mysql cpu 100% 满 优化方案
解决MySQL CPU占用100%的经验总结 - karl_han的专栏 - CSDN博客 https://blog.csdn.net/karl_han/article/details/5630782 ...
- 企业级分布式应用服务EDAS _Dubbo商业版_微服务PaaS平台 【EDAS Serverless 运维 创业】
企业级分布式应用服务EDAS _Dubbo商业版_微服务PaaS平台_分布式框架 - 阿里云https://www.aliyun.com/product/edas?source_type=yqzb_e ...
- 关于controller的书写
private Logger log = LoggerFactory.getLogger(ReportFormController.class); // 读取配置文件 ResourceBundle r ...
- RedHat 安装RabbitMQ
(以下均以root用户执行) 1.安装配置epel源rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noar ...