http://poj.org/problem?id=3468

 

题意:有一个比较长的区间可能是100000.长度, 每个点都有一个值(值还比较大),

现在有一些操作:

C a b c, 把区间a--b内全部加上c

Q a b,求区间ab的值和。

线段树 改变整个区间的数

这题不能直接更新到树的叶子节点, 因为那样时间复杂度太高,我们可以在每个节点上加一个变量k,表示这个节点的所有点(L到R)都要增加 k, 所以我们可以在从上往下查找的过程中如果不是所求区间,那么我们就把本区间加上应该加的数,否则的话,就停止,这样每次更新的过程时间复杂度也是log n,查找时, 我们需要把含有K值得那些点放到它的子节点上去,只需要一层就可以了,具体过程看代码

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; #define INF 0xfffffff
#define N 400050
#define Lson root<<1
#define Rson root<<1|1 struct SegmentTree
{
int L, R;
long long sum, k;
int Mid()
{
return (L+R)>>1;
}
int len()
{
return R-L+1;
}
} a[N<<2]; void BuildSegTree(int root, int L, int R)
{
a[root].L = L;
a[root].R = R;
a[root].k = 0;
if( L == R )
{
scanf("%lld", &a[root].sum);
return ;
} BuildSegTree(Lson, L, a[root].Mid());
BuildSegTree(Rson, a[root].Mid()+1, R); a[root].sum = a[Rson].sum + a[Lson].sum;
} void Update(int root, int L, int R, int k)
{
a[root].sum += (R - L + 1) * k; if(a[root].L == L && a[root].R == R)///当到达要更新的那个区间时,把k值更新,并返回;
{
a[root].k += k;
return ;
} if(R <= a[root].Mid())///右边;
Update(Lson, L, R, k);
else if(L > a[root].Mid())///左边;
Update(Rson, L, R, k);
else///中间;
{
Update(Lson, L, a[root].Mid(), k);
Update(Rson, a[root].Mid()+1, R, k);
}
} void Down(int root)
{
a[Lson].sum += a[Lson].len()*a[root].k;
a[Rson].sum += a[Rson].len()*a[root].k;///左右儿子的和都要增加对应的值,注意这里看清楚增加的是谁;
a[Lson].k += a[root].k;
a[Rson].k += a[root].k;///接着往下传递K值;
a[root].k = 0;///传下去之后就置0;
}
long long Query(int root, int L, int R)
{
if(a[root].L==L && a[root].R == R)///当刚好是这个区间时返回结果;
return a[root].sum; Down(root);///往下传递K值; if(R <= a[root].Mid())
return Query(Lson, L, R);
else if( L > a[root].Mid())
return Query(Rson, L, R);
else
{
long long Lsum = Query(Lson, L, a[root].Mid());
long long Rsum = Query(Rson, a[root].Mid()+1, R);
return Lsum + Rsum;
}
} int main()
{
int n, m, L, R, k;
long long ans;
char s[10];
while(scanf("%d %d", &n, &m) != EOF)
{
BuildSegTree(1, 1, n);
for(int i=0; i<m; i++)
{
scanf("%s", s);
if(s[0] == 'Q')
{
scanf("%d %d", &L, &R);
ans = Query(1, L, R);
printf("%lld\n", ans);
}
else
{
scanf("%d %d %d", &L, &R, &k);
Update(1, L, R, k);
}
}
}
return 0;
}
/*
100
2 3 4 5 6 7 8 9 10
Q 1 5
C 1 10 1
Q 3 5 */

  

A Simple Problem with Integers---poj3468线段树的更多相关文章

  1. POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询)

    POJ.3468 A Simple Problem with Integers(线段树 区间更新 区间查询) 题意分析 注意一下懒惰标记,数据部分和更新时的数字都要是long long ,别的没什么大 ...

  2. POJ3468:A Simple Problem with Integers(线段树模板)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 149972 ...

  3. poj3468 A Simple Problem with Integers(线段树区间更新)

    https://vjudge.net/problem/POJ-3468 线段树区间更新(lazy数组)模板题 #include<iostream> #include<cstdio&g ...

  4. poj 3468:A Simple Problem with Integers(线段树,区间修改求和)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 58269   ...

  5. POJ 3468 A Simple Problem with Integers(线段树区间更新区间查询)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 92632   ...

  6. POJ 3468:A Simple Problem with Integers(线段树区间更新模板)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 141093 ...

  7. POJ 3468 A Simple Problem with Integers(线段树模板之区间增减更新 区间求和查询)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 140120 ...

  8. POJ-3468-A Simple Problem with Integers(线段树 区间更新 区间和)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 139191 ...

  9. poj 3468 A Simple Problem with Integers 【线段树-成段更新】

    题目:id=3468" target="_blank">poj 3468 A Simple Problem with Integers 题意:给出n个数.两种操作 ...

  10. 线段树:POJ3468-A Simple Problem with Integers(线段树注意事项)

    A Simple Problem with Integers Time Limit: 10000MS Memory Limit: 65536K Description You have N integ ...

随机推荐

  1. 设置开机自启动VirtualBox虚拟机系统

    如果常用VirtualBox虚拟机系统的话,设置个随开机启动也是很方便的.不需要打开VirtualBox窗口,直接就是系统启动了. 又继续上网搜索学习了.(设置开机自启动VirtualBox虚拟机系统 ...

  2. vc 关于局部刷新

    在绘制图像对象的时候,时刻获取其所占范围大小,并使用InvalidateRect( m_rectRefresh);刷新,但是光这样还是不行的要在onDraw()函数里获取PAINTSTRUCT结构的无 ...

  3. Java中有几种线程池?

    缓存,修正,计划,单一 newCachedThreadPool newFixedThreadPool newScheduleThreadPool newSingleThreadExecutor

  4. 124、@JavascriptInterface

    targetSdkVersion 是设置希望的SDK版本,如果设置了此属性,那么在程序执行时,如果目标设备的API版本正好等于此数值,他会告诉Android平台:此程序在此版本已经经过充分测,没有问题 ...

  5. 119、 android:hardwareAccelerated="true"or"false"硬件加速的重要性

    每次做项目都会遇见一些特别简单的问题,但是又很费时间来让你解决的问题. 1.本身想实现一个简单的画廊效果,可是每次图片的显示都不能显示在正中的位置,真的很烦人,也花费了很长时间.最终还是知道了原因.解 ...

  6. JavaScript的格式--从格式做起,做最严谨的工程师

    1.JavaScript的格式: JavaScript区分大小写: JavaScript脚本程序须嵌入在HTML文件中: JavaScript脚本程序中不能包含HTML标记代码:(双引号) 每行写一条 ...

  7. Linux虚拟机下mysql 5.7安装配置方法图文教程

    一. 下载mysql5.7 http://mirrors.sohu.com/mysql/MySQL-5.7/ Linux下载: 输入命令:wget http://mirrors.sohu.com/my ...

  8. Android Studio 出现 Gradle's dependency cache may be corrupt 解决方案

    将 .\项目地址\gradle\wrapper\gradle-wrapper.properties 文件中的 gradle版本 与 正常的版本 修改一致即可.

  9. 《转》Python学习(13)-Python的字符编码

    转自 http://www.cnblogs.com/BeginMan/p/3166363.html 一.字符编码中ASCII.Unicode和UTF-8的区别 点击阅读:http://www.cnbl ...

  10. JavaScript—倒计时

    当前时间-倒计时下载 效果: 代码: <!doctype html> <html> <head> <meta http-equiv="Content ...