这是个线段树题目,做之前必须要有些线段树基础才行不然你是很难理解的。

此题的难点就是在于你加的数要怎么加,加入你一直加到叶子节点的话,复杂度势必会很高的

具体思路

在增加时,如果要加的区间正好覆盖一个节点,则增加其节点的Inc值,不再往下走,否则要更新Sum(加上本次增量),再将增量往下传。

这样更新的复杂度就是O(log(n))在查询时,如果待查区间不是正好覆盖一个节点,就将节点的Inc往下带,然后将Inc代表的所有增量累加到Sum上后将Inc清0,接下来再往下查询。

Inc往下带的过程也是区间分解的过程,复杂度也是O(log(n))

明白思路就好写了。

下面是代码

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <cstring>
using namespace std;
#define INF 0xfffffff
#define min(a,b) (a<b?a:b)
#define maxn 100010 #define lson root<<1///左儿子 相当于 root*2
#define rson root<<1|1///右儿子
typedef __int64 LL;
int n, m, val[maxn]; struct node
{
int L, R;
LL Sum, Inc;///Sum保存区间的和, Inc保存这个区间内所有的数字都加上Inc
int Mid()
{
return (L + R)/;
}
} Tree[maxn*]; void Bulid(int root,int L,int R)
{/**递归建树,并且将值进行更新*/
Tree[root].L = L;
Tree[root].R = R;
Tree[root].Sum = Tree[root].Inc = ;
if(L == R)
{
Tree[root].Sum = val[L];
return ;
}
Bulid(lson, L, Tree[root].Mid() );
Bulid(rson, Tree[root].Mid()+, R);
Tree[root].Sum = Tree[lson].Sum + Tree[rson].Sum;
} void Add(int root,int L,int R,int v)
{/**更新区间内所有的值*/
if(L == Tree[root].L && R == Tree[root].R)
{/**如果上述条件满足了,说明整个区间都要加上一个 v,这个时候我们只需要更新 Inc就可以了*/
Tree[root].Inc += v;
return ;
}
/**如果这个区间并不能完全更新完,则将这个值加到Sum上*/
Tree[root].Sum += (R - L + )*v; /**继续向下递增*/
if( R <= Tree[root].Mid() )
Add(lson, L, R, v);
else if(L > Tree[root].Mid() )
Add(rson, L, R, v);
else
{
Add(lson, L, Tree[root].Mid(), v);
Add(rson, Tree[root].Mid()+, R, v);
}
} LL QuerySum(int root,int L,int R)
{
LL Sum = ;
/**查询操作**/
if(Tree[root].L == L && Tree[root].R == R)/**如果区间完全吻合了,可以直接算出来*/
return Tree[root].Inc * (R - L + ) + Tree[root].Sum; /**否则我们需要向下继续更新 Inc*/
Tree[root].Sum += Tree[root].Inc * (Tree[root].R - Tree[root].L + ); Tree[lson].Inc += Tree[root].Inc;
Tree[rson].Inc += Tree[root].Inc; Tree[root].Inc = ;
/**向下递归求和*/
if(L > Tree[root].Mid() )
Sum += QuerySum(rson,L,R);
else if(R <= Tree[root].Mid() )
Sum += QuerySum(lson,L,R);
else
{
Sum += QuerySum(lson,L, Tree[root].Mid() );
Sum += QuerySum(rson,Tree[root].Mid()+, R);
} return Sum;
} int main()
{
int Q;
char ch[];
scanf("%d %d",&n, &Q);
Bulid(,,n);
for(int i=; i<=n; i++)
scanf("%d",&val[i]);
Bulid(,,n); while( Q-- )
{
int a, b, c;
scanf("%s", ch); if(ch[] == 'Q')
{
scanf("%d %d",&a, &b);
printf("%I64d\n", QuerySum(,a,b) );
}
else
{
scanf("%d %d %d",&a, &b, &c);
Add(,a,b,c);
}
}
return ;
}

POJ 3468 A Simple Problem with Integers(详细题解) 线段树的更多相关文章

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

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

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

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

  3. 线段树(成段更新) POJ 3468 A Simple Problem with Integers

    题目传送门 /* 线段树-成段更新:裸题,成段增减,区间求和 注意:开long long:) */ #include <cstdio> #include <iostream> ...

  4. POJ 3468 A Simple Problem with Integers(分块入门)

    题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS   Memory Limit ...

  5. POJ 3468 A Simple Problem with Integers(线段树功能:区间加减区间求和)

    题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS   Memory Limit ...

  6. poj 3468 A Simple Problem with Integers(线段树+区间更新+区间求和)

    题目链接:id=3468http://">http://poj.org/problem? id=3468 A Simple Problem with Integers Time Lim ...

  7. poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和

    A Simple Problem with Integers Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...

  8. poj 3468 A Simple Problem with Integers 线段树区间加,区间查询和(模板)

    A Simple Problem with Integers Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://poj.org/problem?i ...

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

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

随机推荐

  1. Java——(三)Collection之Set集合、HashSet类

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.Set集合 Set集合不允许包含相同的元素,如果试图把两个相同的元素加入同一个Set集合中, ...

  2. colspan是跨列,rowspan是跨行

    colspan是跨列,rowspan是跨行,可以看作是网页设计表格中的列和行的一个属性.跨列相当于把两列或者多列合并成一个单元格:跨行同理是把两行或者多行合并成一行:colspan和rowspan分别 ...

  3. gulp的点点滴滴

    去年用gulp,但一直没有写篇博客,今天有时间无聊写一篇.... 什么是gulp?gulp的官网title上对这个工具有一个比较准确的定义,叫做:基于流的自动化构建工具.如果你查看它的网页源代码,还会 ...

  4. Hibernate 的HQL语句,初级

    这里讲解简单的HQL语句,因为很多比较复杂的外查询,用一般的查询很难完成 所以这里需要使用HQL @Test public void selquery(){ System.out.printf(&qu ...

  5. Canvas模糊化处理图片、毛玻璃处理图片之stackblur.js

    Canvas实现毛玻璃效果解决方式1:使用stackblur.js 在Android系统中实现图片的毛玻璃效果比较好用的类库是:Android StackBlur 官方Git地址:https://gi ...

  6. Two ways to create file using 'doc'.

    Here are two ways to create file using 'doc' command: Method i: copy con [file name][enter key] [con ...

  7. VS2015使用OSChina的git功能

    好长时间没有写博了,把今天的新的记录一下. 最近开始使用vs2015,vs2015支持git平台和TF功能,因为....,我选择了OSChina的git.一开始学习的此篇文章http://my.osc ...

  8. Dell服务器MegaCli命令只返回Exit Code: 0x00问题分析

    今天同事给我说一台dell的服务器做了raid后,使用MegaCli看不到raid信息,上去看了一下确实不返回任何raid信息,但是确实机器上做了raid. 这就奇怪了,然后把MegaCli升级到最新 ...

  9. oracle命令的缩写原型单词方便记忆总结

    $ORACLE_HOME/bin下的utilities解释 Binary              First Available        Description adapters        ...

  10. iOS多线程的初步研究(八)-- dispatch队列

    GCD编程的核心就是dispatch队列,dispatch block的执行最终都会放进某个队列中去进行,它类似NSOperationQueue但更复杂也更强大,并且可以嵌套使用.所以说,结合bloc ...