线段树(单点更新and成段更新)
线段树需要的空间。
区间为1-->n
假设是一棵完全二叉树,且树高为i。
完全二叉树性质:第i层最多有2^(i-1)个结点。
那么 2^(i-1) = n; i = log2(n) + 1;
共有 2^i - 1 个结点, 即 2^(log2(n) + 1) - 1个结点
即2 * 2^log2(n) - 1 = 2 * n - 1
但这是建立树是完全二叉树的情况下。

但是如图所示,树可能不是完全二叉树,最下面一层的结点个数>n, 我们以2n来来计算,那么就需要4*n-1的空间。
http://acm.hdu.edu.cn/showproblem.php?pid=1166
单点更新
#include <stdio.h>
#include <string.h>
const int N = ;
int a[N*],ans;
void swap(int &a, int &b)
{
int t = a;
a = b;
b = t;
}
void build(int rt, int l, int r)
{
if(l==r)
{
scanf("%d",&a[rt]);
return;
}
int mid = (l + r) >> ;
build(rt<<,l,mid);
build(rt<<|,mid+,r);
a[rt] = a[rt<<] + a[rt<<|];
} void query(int rt, int L, int R, int l, int r)
{
if(L==l && R==r)
{
ans += a[rt];
return;
}
int mid = (l + r) >> ;
if(R<=mid)
query(rt<<,L,R,l,mid);
else if(L>mid)
query(rt<<|,L,R,mid+,r);
else
{
query(rt<<,L,mid,l,mid);
query(rt<<|,mid+,R,mid+,r);
}
}
void update(int rt, int val, int pos, int l, int r)
{
if(l == r)
{
a[rt] += val;
return ;
}
int mid = (l + r) >> ;
if(pos <= mid)
update(rt<<,val,pos,l,mid);
else
update(rt<<|,val,pos,mid+,r);
a[rt] = a[rt<<] + a[rt<<|];
}
int main()
{
int t,n,i,j,tCase;
char str[];
scanf("%d",&t);
for(tCase=; tCase<=t; ++tCase)
{
memset(a,,sizeof(a));
scanf("%d",&n);
build(,,n);
printf("Case %d:\n",tCase);
while(true)
{
scanf("%s",str);
if(str[]=='E')
break;
scanf("%d%d",&i,&j);
if(str[]=='Q')
{
ans = ;
if(i > j)
swap(i,j);
query(,i,j,,n);
printf("%d\n",ans);
}
else if(str[]=='A')
{
update(,j,i,,n);
}
else
update(,-j,i,,n);
}
}
return ;
}
http://acm.hdu.edu.cn/showproblem.php?pid=1698
成段更新, 要用到懒惰标记,每次更改区间时,不会更新到叶子结点,而是标记,等有需要了才去更新
#include <stdio.h>
#include <string.h>
const int N = + ;
struct node
{
int sum;
int tag;
}a[N*];
void pushUp(int rt)
{
a[rt].sum = a[rt<<].sum + a[rt<<|].sum;
}
void pushDown(int rt, int m)
{
if(a[rt].tag != )
{
a[rt<<].tag = a[rt<<|].tag = a[rt].tag;
a[rt<<].sum = (m-(m>>)) * a[rt].tag;
a[rt<<|].sum = (m>>) * a[rt].tag;
a[rt].tag = ;
}
}
void build(int rt, int l, int r)
{
a[rt].tag = ;
if(l==r)
{
a[rt].sum = ;
return ;
}
int mid = (l + r) >> ;
build(rt<<,l,mid);
build(rt<<|,mid+,r);
pushUp(rt);
}
void update(int rt, int L, int R, int val, int l, int r)
{
if(L<=l && r<=R)
{
a[rt].sum = (r-l+)*val;
a[rt].tag = val;
return;
}
pushDown(rt,r-l+);
int mid = (l + r) >> ;
if(L<=mid) update(rt<<,L,R,val,l,mid);
if(R>mid) update(rt<<|,L,R,val,mid+,r);
pushUp(rt);
} int main()
{
int t,tCase,n,i,x,y,z,q;
scanf("%d",&t);
for(tCase=; tCase<=t; ++tCase)
{
scanf("%d",&n);
build(,,n);
scanf("%d",&q);
for(i=; i<q; ++i)
{
scanf("%d%d%d",&x,&y,&z);
update(,x,y,z,,n);
}
printf("Case %d: The total value of the hook is %d.\n",tCase,a[].sum);
}
return ;
}
线段树(单点更新and成段更新)的更多相关文章
- 线段树(多维+双成段更新) UVA 11992 Fast Matrix Operations
题目传送门 题意:训练指南P207 分析:因为矩阵不超过20行,所以可以建20条线段的线段树,支持两个区间更新以及区间查询. #include <bits/stdc++.h> using ...
- POJ 2155 Matrix (二维线段树入门,成段更新,单点查询 / 二维树状数组,区间更新,单点查询)
题意: 有一个n*n的矩阵,初始化全部为0.有2中操作: 1.给一个子矩阵,将这个子矩阵里面所有的0变成1,1变成0:2.询问某点的值 方法一:二维线段树 参考链接: http://blog.csdn ...
- HDU 1754 I Hate It 线段树(单点更新,成段查询)
题目链接: hdu: http://acm.hdu.edu.cn/showproblem.php?pid=1754 题解: 单点更新,成段查询. 代码: #include<iostream> ...
- ACM: Copying Data 线段树-成段更新-解题报告
Copying Data Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description W ...
- HDU 1698 Just a Hook(线段树成段更新)
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- Problem 1007 幸运数 线段树成段更新
题目链接: 题目 Problem 1007 幸运数 Time Limit: 2000 mSec Memory Limit : 131072 KB 问题描述 皮特的幸运数是2和5.只由幸运数字2和5组成 ...
- Codeforces Round #149 (Div. 2) E. XOR on Segment (线段树成段更新+二进制)
题目链接:http://codeforces.com/problemset/problem/242/E 给你n个数,m个操作,操作1是查询l到r之间的和,操作2是将l到r之间的每个数xor与x. 这题 ...
- POJ 2777 Count Color (线段树成段更新+二进制思维)
题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的 ...
- Codeforces295A - Greg and Array(线段树的成段更新)
题目大意 给定一个序列a[1],a[2]--a[n] 接下来给出m种操作,每种操作是以下形式的: l r d 表示把区间[l,r]内的每一个数都加上一个值d 之后有k个操作,每个操作是以下形式的: x ...
随机推荐
- 《深入理解mybatis原理》 MyBatis事务管理机制
MyBatis作为Java语言的数据库框架,对数据库的事务管理是其很重要的一个方面.本文将讲述MyBatis的事务管理的实现机制. 首先介绍MyBatis的事务Transaction的接口设计以及其不 ...
- 枚举类型互相转换(使用GetEnumName和TypeInfo两个函数)
usesClasses,TypInfo ; typeTCommandType = (ctEmptyCommand,ctAdd,ctModify); TCommandTypeConvert=classp ...
- 96 Stocks APIs: Bloomberg, NASDAQ and E*TRADE
Our API directory now includes 96 stocks APIs. The newest is the Eurex VALUES API. The most popula ...
- linux串口编程总结
串口本身.标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口以前被广泛用于连接计算机和终端设备和各种外部设备.尽管以太网接口和USB接口也是以一个串行流进行数据传送的.可是串口连接 ...
- 初窥Linux 之 区分硬连接和软连接
一.Linux下的两种连接文件及创建方式 在Linux下面的连接文件有两种——软连接和硬连接,虽然都是连接文件,但两者却有很大的区别.一种是类似于Windows的快捷方式功能的文件(或目录),这种连接 ...
- [Windows Phone学习笔记]UserControl的使用
UserControl的使用 开发过程中,多个UI控件需要协同工作,相互交互之后,才可完成一个完整的业务需求,此时可把这些控件封装成为一个整体,相互之间的交互逻辑封装其中,外部调用可无需关心内部逻辑, ...
- Android应用中Back键的监听及处理
MainActivity如下: package cn.testnbackpressed; import android.os.Bundle; import android.view.KeyEvent; ...
- xcode 改动整个项目名
目标为:将项目名XCD4改成xcd5. 先上结果图:==> 1.在左側的导航区域点击两次项目名,两次间隔时间略微长些,项目名会变成可编辑状态. 将名称改动为xcd5后按enter键弹出一个对话框 ...
- IBM之MQ使用指南
随着计算机网络和分布式应用的不断发展.远程消息传递越来越成为应用系统中必不可少的组成部分. 商业消息中间件的出现保证了消息传输的可靠性,高效率和安全性,同一时候也降低了系统的开发周期. 眼下应用最多的 ...
- configure: error: zlib not installed
export LDFLAGS="-L/usr/local/zlib/lib" export CPPFLAGS="-I/usr/local/zlib/include&quo ...