Description

You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4

Sample Output

4
55
9
15

Hint

The sums may exceed the range of 32-bit integers.

Source

【分析】
很不错的数据结构,真的很不错....
跟树状数组有点像..
相比与普通线段树,zkw线段树具有标记永久化,简单好写的特点。
但zkw线段树占用的空间会相对大些,毕竟是2的阶乘...,然后应该不能可持久化吧(别跟我说用可持久化线段树维护可持久化数组....)
这样就不能动态分配内存了。。不过总体来说还是有一定的实用价值...
 /*
宋代陆游
《临安春雨初霁》 世味年来薄似纱,谁令骑马客京华。
小楼一夜听春雨,深巷明朝卖杏花。
矮纸斜行闲作草,晴窗细乳戏分茶。
素衣莫起风尘叹,犹及清明可到家。
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <assert.h>
#include <map>
#include <ctime>
#include <cstdlib>
#include <stack>
#define LOCAL
const int INF = 0x7fffffff;
const int MAXN = + ;
const int maxnode = ;
using namespace std;
struct Node{
int l, r;
long long sum, d;
}tree[maxnode];
int data[MAXN], M;//M为总结点个数 //初始化线段树
void build(int l, int r){
for (int i = * M - ; i > ; i--){
if (i >= M){
tree[i].sum = data[i - M];
tree[i].l = tree[i].r = (i - M);//叶子节点
}
else {
tree[i].sum = tree[i<<].sum + tree[(i<<)+].sum;
tree[i].l = tree[i<<].l;
tree[i].r = tree[(i<<)+].r;
}
}
}
long long query(int l, int r){
long long sum = ;//sum记录和
int numl = , numr = ;
l += M - ;
r += M + ;
while ((l ^ r) != ){
if (~l&){//l取反,表示l是左节点
sum += tree[l ^ ].sum;
numl += (tree[l ^ ].r - tree[l ^ ].l + );
}
if (r & ){
sum += tree[r ^ ].sum;
numr += (tree[r ^ ].r - tree[r ^ ].l + );
}
l>>=;
r>>=;
//numl,numr使用来记录标记的
sum += numl * tree[l].d;
sum += numr * tree[r].d;
}
for (l >>= ; l > ; l >>= ) sum += (numl + numr) * tree[l].d;
return sum;
} void add(int l, int r, int val){
int numl = , numr = ;
l += M - ;
r += M + ;
while ((l ^ r) != ){
if (~l&){//l取反
tree[l ^ ].d += val;
tree[l ^ ].sum += (tree[l ^ ].r - tree[l ^ ].l + ) * val;
numl += (tree[l ^ ].r - tree[l ^ ].l + );
}
if (r & ){
//更新另一边
tree[r ^ ].d += val;
tree[r ^ ].sum += (tree[r ^ ].r - tree[r ^ ].l + ) * val;
numr += (tree[r ^ ].r - tree[r ^ ].l + );
}
l>>=;
r>>=;
tree[l].sum += numl * val;
tree[r].sum += numr * val;
}
//不要忘了往上更新
for (l >>= ; l > ; l >>= ) tree[l].sum += (numl+numr) * val;
}
int n, m; void init(){
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++) scanf("%d", &data[i]);
M = ;while (M < (n + )) M <<= ;//找到最大的段
build(, M - );
}
void work(){
while (m--){
char str[];
scanf("%s", str);
if (str[] == 'Q'){
int l, r;
scanf("%d%d", &l, &r);
printf("%lld\n", query(l, r));
}
else{
int val, l, r;
scanf("%d%d%d", &l, &r, &val);
if (val != ) add(l, r, val);
}
}
} int main(){ init();
work();
return ;
}

【POJ3468】【zkw线段树】A Simple Problem with Integers的更多相关文章

  1. 线段树---poj3468 A Simple Problem with Integers:成段增减:区间求和

    poj3468 A Simple Problem with Integers 题意:O(-1) 思路:O(-1) 线段树功能:update:成段增减 query:区间求和 Sample Input 1 ...

  2. poj3468 A Simple Problem with Integers (线段树区间最大值)

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

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

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

  4. POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)

    A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...

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

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

  6. POJ3648 A Simple Problem with Integers(线段树之成段更新。入门题)

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

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

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

  8. poj 3468 A Simple Problem with Integers 线段树第一次 + 讲解

    A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal w ...

  9. Poj 3468-A Simple Problem with Integers 线段树,树状数组

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

随机推荐

  1. 2015第43周一solr相关概念

    Solr是一种开放源码的.基于Lucene的搜索服务器.它易于安装和配置,而且附带了一个基于HTTP 的管理界面.   官网:http://lucene.apache.org/solr/ solr学习 ...

  2. Google Map API 学习2-界面展示

  3. Spark如何解决常见的Top N问题

    需求   假设我们有一张各个产品线URL的访问记录表,该表仅仅有两个字段:product.url,我们需要统计各个产品线下访问次数前10的URL是哪些?   解决方案   (1)模拟访问记录数据   ...

  4. TCP连接建立的三次握手过程可以携带数据吗?

    前几天实验室的群里扔出了这样一个问题:TCP连接建立的三次握手过程可以携带数据吗?突然发现自己还真不清楚这个问题,平日里用tcpdump或者Wireshark抓包时,从来没留意过第三次握手的ACK包有 ...

  5. The breakpoint will not currently be hit. vs2005断点不被命中

    用会了vs2005但是发现坑爹的连断点都不会命中,原来是默认设置的问题.要使断点命中: 1. 首先确保程序是在DEBUG模式下运行: 2. 确认正确的项目设置:链接器->调试->生成调试信 ...

  6. string.Format字符串格式说明

    先举几个简单的应用案例: 1.格式化货币(跟系统的环境有关,中文系统默认格式化人民币,英文系统格式化美元) string.Format("{0:C}",0.2) 结果为:¥0.20 ...

  7. Away3D 的实体收集器流程2

    带着上次的疑问我们继续探讨Away3D 的渲染流程. 在Away3D中所有的显示对象都是继承Object3D 的我们先看看显示对象和继承关系. Object3D |---ObjectContainer ...

  8. 初次接触GWT,知识点总括

    初次接触GWT,知识点概括 前言 本人最近开始研究 GWT(Google Web Toolkit) ,现将个人的一点心得贴出来,希望对刚开始接触 GWT的程序员们有所帮助,也欢迎讨论,共同进步. 先说 ...

  9. 解决IE6,IE7不能隐藏绝对定位溢出的内容

    令人蛋疼的IE,IE6/IE7下父元素有相对/绝对定位时,子元素在IE6和IE7下overflow:hidden;失效. 情况一:(在parent上增加position:relative) <s ...

  10. [Angular 2] Keynote: Lazy Routing -- NGCONF

    So How to do lazy loading for router in Angular 2. The nomarl way to write a router in Angular 2: Yo ...