NYOJ 116士兵杀敌(二) 树状数组
题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=116
士兵杀敌(一) 数组是固定的,所以可以用一个sum数组来保存每个元素的和就行,但是不能每次都加,因为那样会超时,查询次数太多。但是这个士兵杀敌(二)就不能用那个方法来解了,因为这个是动态的,中间元素的值可能会变化,所以引出一个新的东西来。刚开始想了一下,实在是没有想到方法,就去讨论区看了看,一看好像都说用树状数组,就去找树状数组的用法。
先上图,看着图解释容易理解点。
数组A是原数组中的元素,数组C是树状数组中的元素,图中C数组的元素组成为A中的某些元素之和,这些元素的个数取决于它的下标能被多少个2整除,像C[1] = A[1]; C[2] = A[1] + A[2]; C[3] = A[3]; C[4] = A[1] + A[2] + A[3] + [4] = C[2] + C[3]; ……这些个数可以写一个通式C[i] = A[n - 2^k + 1] + ……+A[i]; 其中k为 i 的二进制中从右往左数的 0 的个数 ,就像6有一个, 6可以写成 2 × 3, 所以C[6] = A[5] + A[6]; 所以可以定义一个函数来求这个数.
6的二进制为0110
5的二进制为0101
6^5 = 0011
6&(6^5) = 0010 = 十进制中的2
所以函数可以这么写
int lowbit(int N)//求n中有多少个能被2的多少次幂整除的,即2^k, 也就是树状数组的作用域
{
return N & (N ^ (N - ));
}
也可以写成
int lowbit(int N)//求n中有多少个能被2的多少次幂整除的,即2^k, 也就是树状数组的作用域
{
return N & (-N);
}
更改一个数的值, 就要更改次数在树状数组中的所有祖先,不过这个时间复杂度是O(logn); 下面是更改值(添加杀敌数)的函数
void add(int pos, int num)//添加新值到树状数组中
{
while(pos <= n)
{
tmp[pos] += num;
pos += lowbit(pos);
}
}
下面就是求和函数, 因为这种方法之所以快,是求他的最小树根节点的和, 最小树的个数为当前要求的n的二进制中为1的个数,即展开式中能写成不同2的幂指数的项数,
例如: 15 = 2^3 + 2^2 + 2^1 + 2^0; 所以n = 15时, 最小数有四个,求和的时间复杂度为O(logn);
int Sum(int N)//求前N个数的和
{
int sum = ;
while(N > )
{
sum += tmp[N];
N -= lowbit(N);
}
return sum;
}
关键就是这三步, 这三步搞明白了,基本上就不成问题了,但是,当时按照 杀敌(一) 中的思维,还统计了一个总数,那样不会快,反而会慢,所以直接求就行,下面是完整的代码
#include <stdio.h>
#include <string.h> int tmp[];
int n, k; int lowbit(int N)//求n中有多少个能被2的多少次幂整除的,即2^k, 也就是树状数组的作用域
{
return N & (-N);
} void add(int pos, int num)//添加新值到树状数组中
{
while(pos <= n)
{
tmp[pos] += num;
pos += lowbit(pos);
}
} int Sum(int N)//求前N个数的和
{
int sum = ;
while(N > )
{
sum += tmp[N];
N -= lowbit(N);
}
return sum;
} int main()
{
int a, b, temp;
char str[];
scanf("%d %d", &n, &k);
for(int i = ; i <= n; i++)
{
scanf("%d", &temp);
add(i, temp);
}
for(int i = ; i < k; i++)
{
scanf("%s %d %d", str, &a, &b);
if(strcmp(str, "QUERY") == )
printf("%d\n", Sum(b) - Sum(a - ));
else
add(a, b);
} return ;
}
NYOJ 116士兵杀敌(二) 树状数组的更多相关文章
- NYOJ 116 士兵杀敌二
士兵杀敌(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军经常 ...
- NYOJ 116 士兵杀敌 (线段树,区间和)
题目链接:NYOJ 116 士兵杀敌 士兵杀敌(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描写叙述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的 ...
- NYOJ 116 士兵杀敌(二)【线段树 单点更新】
题意:题意非常清楚: 策略:如题. 这道题就是简单的线段树应用,据说还能够用树状数组来做,等我学了之后在说吧. 代码: #include<stdio.h> #include<stri ...
- NYOJ 231 Apple Tree (树状数组)
题目链接 描述 There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in t ...
- NYOJ 116 士兵杀敌(二) (树状数组)
题目链接 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的.小工是南将军手下的军师,南将军经常想知道第m号到第n号士兵的总杀敌数,请你帮助小工来回答南将军吧.南将军的某次询问之后 ...
- nyoj 116 士兵杀敌(二)【线段树单点更新+求和】
士兵杀敌(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军经常 ...
- nyoj 116 士兵杀敌(二)(线段树、单点更新)
士兵杀敌(二) 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的军师,南将军经常 ...
- NYOJ 116 士兵杀敌(二)(二叉索引树)
http://acm.nyist.net/JudgeOnline/problem.php?pid=116 题意: 南将军手下有N个士兵,分别编号1到N,这些士兵的杀敌数都是已知的. 小工是南将军手下的 ...
- hdoj-4417(做法二 树状数组离线解法,对所有的查询先保存进行排序后有序的查询) 好腻害!
#include<cstdio> #include<cstring> #include<algorithm> using namespace std;; ; str ...
随机推荐
- linux dd命令测试U盘读写速度
1. dd命令简述: if=输入文件, of=输出文件, ibs=一次读取字节数, obs=一次写入字节数, bs=设置一次读取写入的字节数, skip=跳过的bs数, count=拷贝的块数 2. ...
- Linux 0.11下信号量的实现和应用
Linux 011下信号量的实现和应用 生产者-消费者问题 实现信号量 信号量的代码实现 关于sem_wait和sem_post sem_wait和sem_post函数的代码实现 信号量的完整代码 实 ...
- ueditor 1.4.3.2 独立/单独 上传图片框原理
其实简单的说就是编辑框很多按钮,所有按钮的功能都是以command形式提供,所以execCommand就是执行这些功能的命令.有些按钮是能弹出显示一个对话框,他的基类就是dialog,而所有被弹出的d ...
- jQuery图片提示示例
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 使用Gson进行json数据转换(list to json 和json to list)
文章借鉴自:http://blog.csdn.net/binyao02123202/article/details/7540407 下面是一个简单的例子: Java代码 public class Pe ...
- 我的sublime常用快捷键
sublime一般被应用于前端开发,在实际开发中,我们常用的sublime快捷键有哪些呢?这里汇总一下,常用的排在前面. 常用快捷键 Ctrl+Shift+P:打开命令面板 Ctrl+D:选择重复单词 ...
- 微信小程序开发之大坑记之post请求
原文:http://blog.csdn.net/walkingmanc/article/details/54237961 在微信小程序开发过程中,如果你完全按照官方文档来,那么恭喜你,90%的可能性你 ...
- 状态机的c语言编程
http://blog.csdn.net/shandongdaya/article/details/7282547 一 有限状态机的实现方式 有限状态机(Finite State Machine或者F ...
- 百度地图LBS云平台读写数据操作类
最近写了个叫<行踪记录仪>的手机软件,用了百度云来记录每个用户的最近位置,以便各用户能在地图上找到附近的人,为此写了个类来读写数据,大致如下: import java.util.Array ...
- asp.net(C#)写SQL语句技巧
/*添加SQL*/string fields = "";string values = "";fields += "xm"; values ...