线段树需要的空间。

区间为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成段更新)的更多相关文章

  1. 线段树(多维+双成段更新) UVA 11992 Fast Matrix Operations

    题目传送门 题意:训练指南P207 分析:因为矩阵不超过20行,所以可以建20条线段的线段树,支持两个区间更新以及区间查询. #include <bits/stdc++.h> using ...

  2. POJ 2155 Matrix (二维线段树入门,成段更新,单点查询 / 二维树状数组,区间更新,单点查询)

    题意: 有一个n*n的矩阵,初始化全部为0.有2中操作: 1.给一个子矩阵,将这个子矩阵里面所有的0变成1,1变成0:2.询问某点的值 方法一:二维线段树 参考链接: http://blog.csdn ...

  3. HDU 1754 I Hate It 线段树(单点更新,成段查询)

    题目链接: hdu: http://acm.hdu.edu.cn/showproblem.php?pid=1754 题解: 单点更新,成段查询. 代码: #include<iostream> ...

  4. ACM: Copying Data 线段树-成段更新-解题报告

    Copying Data Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u Description W ...

  5. HDU 1698 Just a Hook(线段树成段更新)

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  6. Problem 1007 幸运数 线段树成段更新

    题目链接: 题目 Problem 1007 幸运数 Time Limit: 2000 mSec Memory Limit : 131072 KB 问题描述 皮特的幸运数是2和5.只由幸运数字2和5组成 ...

  7. 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. 这题 ...

  8. POJ 2777 Count Color (线段树成段更新+二进制思维)

    题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的 ...

  9. Codeforces295A - Greg and Array(线段树的成段更新)

    题目大意 给定一个序列a[1],a[2]--a[n] 接下来给出m种操作,每种操作是以下形式的: l r d 表示把区间[l,r]内的每一个数都加上一个值d 之后有k个操作,每个操作是以下形式的: x ...

随机推荐

  1. WebBrowser脚本错误的完美解决方案

    原文:WebBrowser脚本错误的完美解决方案   当IE浏览器遇到脚本错误时浏览器,左下角会出现一个黄色图标,点击可以查看脚本错误的详细信息,并不会有弹出的错误信息框.当我们使用WebBrowse ...

  2. 几款屏幕录制软件 ActivePresente

    几款屏幕录制软件,最强大是  ActivePresenter ,免费版, 足以应对我们日常需求.列表如下 支持系统:W-Windows,L-Linux,M-Mac 软件 格式 W L M 免费 说明 ...

  3. C语言数据结构----递归的应用(斐波拉契数列、汉诺塔、strlen的递归算法)

    本节主要说了递归的设计和算法实现,以及递归的基本例程斐波拉契数列.strlen的递归解法.汉诺塔和全排列递归算法. 一.递归的设计和实现 1.递归从实质上是一种数学的解决问题的思维,是一种分而治之的思 ...

  4. 管道实现进程间通讯 、WaitNamedPipe

    一.管道实现进程间通讯 主要的理论知识 1.什么是管道以及分类 管道是两个头的东西,每一个头各连接一个进程或者同一个进程的不同代码,依照管道的类别分有两种管道,匿名的和命名的:依照管道的传输方向分也能 ...

  5. Tokyo Tyrant(TTServer)系列(四)-tcrmgr远程管理与调试

    Tokyo Tyrant(TTServer)系列-tcrmgr(远程管理与调试) tcrmgr是TokyoTyrant的管理工具,对ttserver进行管理与执行命令: 通过输入tcrmgr回车,能够 ...

  6. 可运行jar包调用exe可运行文件,子进程阻塞

    背景: 须要在项目的測试工具中加入一个button,点击后直接打开某exe工具. 这个工具的功能是导入txt文件,转为excel报表输出. 无奈解析了两行之后就停止不动了,也不报错.关闭測试工具后,就 ...

  7. Java Runtime.getRuntime().exec() 执行带空格命令

    可执行文件路径如果包含空格,则在java中不能被获取到. 此时Debug一下,会发现 project=null. project.waitFor 的返回值为1.但是去源路径单击bat文件是可以正常运行 ...

  8. hdu 4291 A Short problem(矩阵+取模循环节)

    A Short problem                                                          Time Limit: 2000/1000 MS (J ...

  9. ym——Android开发编码规范(自用)

    转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! Android开发编码规范 目的及指导原则 目的 统一规范 Eclipse编辑环境下J ...

  10. Android中倒计时代码

    布局: maina.xml <DigitalClock android:id="@+id/myClock" android:layout_width="wrap_c ...