题目一:http://poj.org/problem?id=3468

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 abc" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.

"Q ab" 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.

裸的区间更新,关于lazy标记,还是老话,在下一次更新或询问时才把区间信息传递(pushdown)下去。

代码:

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define Max 100020
long long a,b,q,n;
long long sum[Max<<2],c,lazy[Max<<2];
void pushup(int rt)
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void pushdown(int rt,int m)
{
if(lazy[rt])
{
lazy[rt<<1] += lazy[rt];
lazy[rt<<1|1] += lazy[rt];
sum[rt<<1] += lazy[rt] * (m - (m>>1));
sum[rt<<1|1] += lazy[rt] * (m>>1);
lazy[rt] = 0;
}
}
void build(int l,int r,int rt)
{
sum[rt] = 0;
if(l == r)
{
scanf("%lld",&sum[rt]);
return;
}
int m = (r + l)>>1;
build(lson);
build(rson);
pushup(rt);
}
void Add(int L,int R,int v,int l,int r,int rt)
{
if(L <= l&&r <= R)
{
lazy[rt] += v;
sum[rt] += (long long)(r - l + 1) * v;
return ;
}
pushdown(rt,r-l+1);
int m = (r + l)>>1;
if(L <= m) Add(L,R,v,lson);
if(m < R) Add(L,R,v,rson);
pushup(rt);
}
long long query(int L,int R,int l,int r,int rt)
{
if(L <= l&&r <= R)
{
return sum[rt];
}
long long rec = 0;
int m = (r + l)>>1;
pushdown(rt,r-l+1);
if(L <= m) rec += query(L,R,lson);
if(m < R) rec += query(L,R,rson);
return rec;
}
int main()
{
scanf("%d%d",&n,&q);
build(1,n,1);
while(q--)
{
char qus[2];
scanf("%s",&qus);
if(qus[0] == 'C')
{
scanf("%d%d%d",&a,&b,&c);
Add(a,b,c,1,n,1);
}
else
{
scanf("%d%d",&a,&b);
printf("%lld\n",query(a,b,1,n,1));
} }
return 0;
}

题型二:http://acm.hdu.edu.cn/showproblem.php?pid=1698

把上题的求和改成更新区间值就可以了。

代码如下:

#include<iostream>
#include<cstdio>
#define Max 100010
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int sum[Max<<2],lazy[Max<<2];
void pushup(int rt)
{
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void pushdown(int rt,int INL)
{
if(lazy[rt])
{
lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
sum[rt<<1] = lazy[rt] * (INL - (INL>>1));
sum[rt<<1|1] = lazy[rt] * (INL>>1);
lazy[rt] = 0;
}
}
void build(int l,int r,int rt)
{
lazy[rt] = 0;
sum[rt] = 1;
if(r == l)
{
return;
}
int m = (r + l) >> 1;
build(lson);
build(rson);
pushup(rt);
}
void update(int L,int R,int val,int l,int r,int rt)
{
if(L <= l&&r <= R)
{
sum[rt] = val * (r-l+1);
lazy[rt] = val;
return;
}
pushdown(rt,r-l+1);
int m = (r + l)>>1;
if(L <= m) update(L,R,val,lson);
if(m < R) update(L,R,val,rson);
pushup(rt);
}
int main()
{
int T,n,x,y,z,q;
scanf("%d",&T);
int lala = T;
while(T--)
{
scanf("%d",&n);
build(1,n,1);
scanf("%d",&q);
while(q--)
{
scanf("%d%d%d",&x,&y,&z);
update(x,y,z,1,n,1);
}
printf("Case %d: The total value of the hook is %d.\n",(lala-T),sum[1]);
}
return 0;
}

【题型三-hdu-ColorTheBall】http://acm.hdu.edu.cn/showproblem.php?pid=1556

题意:把a,b区间的 气球都涂上颜色,输出每个气球被涂色的次数。

思路:每次更新只记录到所更新的区间便不再往下记录更新,不需要pushup,只需要在输出时pushdown更新一次到每个节点就可以了

经验教训: 不要用cout, 不要用cout, 不要用cout!

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 100010
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int lazy[maxn<<4];
int n;
//int index[maxn];
void build(int l, int r, int rt)
{
int m;
m = (l + r)>>1;
lazy[rt] = 0;
if(l == r) return;
build(lson);
build(rson);
} void pushdown(int rt)
{
if(lazy[rt])
{
lazy[rt<<1] += lazy[rt];
lazy[rt<<1|1] += lazy[rt];
lazy[rt] = 0;
}
} void paint(int l, int r, int rt, int L, int R)
{
if(L <= l && r <= R)
{
lazy[rt]++;
return ;
}
int m = (r+l)>>1;
if(L <= m) paint(lson, L,R);
if(m < R) paint(rson, L, R);
} void finalQuery(int l, int r, int rt)
{
int m = (l+r)>>1;
if(l == r)
{
printf("%d%c",lazy[rt],l==n?'\n':' ');
return;
}
pushdown(rt); //在查询的时候才pushdown
finalQuery(lson);
finalQuery(rson);
} int main()
{
while(scanf("%d", &n) != EOF&&n)
{
build(1,n,1);
for(int i = 0; i < n; i++)
{
int a, b;
scanf("%d%d", &a, &b);
paint(1, n, 1, a, b);
//cout<<"-"<<endl;
}
finalQuery(1, n, 1);
}
return 0;
}

ccnu-线段树-简单的区间更新(三题)的更多相关文章

  1. HDOJ--4893--Wow! Such Sequence!【线段树+单点、区间更新】

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 题意:给你一个长度n的数列,初始都为0.有三种操作,第一种给第k个位置的数加d.另外一种是查询区间 ...

  2. HDU4893【线段树单点、区间更新】

    题目链接[http://acm.hdu.edu.cn/showproblem.php?pid=4893] 题意:输入n.q.表示有n个数,初始化默认这n个数都为零,有q次操作,操作种类分为三种:1.输 ...

  3. codevs 1082 线段树练习 3 区间更新+延迟标记

    题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 Input Description 第一行一个正整数n,接下 ...

  4. codevs 1081 线段树练习 2 区间更新 单点查询 无lazy

    题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有数都增加X 2:询问第i个数是什么? 输入描述 Input Description 第一行一个正整数n,接下来n行n ...

  5. 洛谷 P3373:【模板】线段树 2(区间更新)

    题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含三个整数N.M.P,分别 ...

  6. HDU 3577Fast Arrangement(线段树模板之区间增减更新 区间求和查询)

    Fast Arrangement Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

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

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

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

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

  9. 线段树简单入门 (含普通线段树, zkw线段树, 主席树)

    线段树简单入门 递归版线段树 线段树的定义 线段树, 顾名思义, 就是每个节点表示一个区间. 线段树通常维护一些区间的值, 例如区间和. 比如, 上图 \([2, 5]\) 区间的和, 为以下区间的和 ...

随机推荐

  1. hdu 5691 Sitting in Line 状压dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5691 题解: 和tsp用的状压差不多,就是固定了一些访问顺序. dp[i][j]表示前cnt个点中布 ...

  2. ios 判断空字符串

    - (BOOL) isBlankString:(NSString *)string { if (string == nil || string == NULL) { return YES; } if ...

  3. Topcoder srm 632 div2

    脑洞太大,简单东西就是想复杂,活该一直DIV2; A:水,基本判断A[I]<=A[I-1],ANS++; B:不知道别人怎么做的,我的是100*N*N;没办法想的太多了,忘记是连续的数列 我们枚 ...

  4. EF 中更新模型的问题,这种错误(因为相同类型的其他实体已具有相同的主键值。)

    在EF经常在更新模型的时候可能会同时操作一个实体几次. 其实除了SaveChanges外,其它的几次基本都是要查询出一个结果, 例如更新的时候,我们要查一下这个表中有没有相同的纪录之类的. 查询完之后 ...

  5. HDU5002 Tree(LCT)

    今天做了一道LCT模板题之后忽然间好像记起来LCT的模板怎么用了,于是就把上次网络赛的一道LCT补一下.典型的删边,加边操作,还有路径加和路径set为一个数.维护的是路径第二大以及它有多少个,后来想想 ...

  6. POJ1811 Prime Test(miller素数判断&&pollar_rho大数分解)

    http://blog.csdn.net/shiyuankongbu/article/details/9202373 发现自己原来的那份模板是有问题的,而且竟然找不出是哪里的问题,所以就用了上面的链接 ...

  7. cf 403 D

    D. Beautiful Pairs of Numbers time limit per test 3 seconds memory limit per test 256 megabytes inpu ...

  8. typedef (还需经常看看加深理解)

    看了 c++primer 1,typedef名字 typedef定义以关键字typedef开始,后面是 数据类型+标示符. 并未引入新的类型,只是现有数据类型的同义词 例: typedef doubl ...

  9. HTML CSS——margin与padding的初学

    下文引自HTML CSS——margin和padding的学习,作者fengyv,不过加入了一些个人的看法. 你在学习margin和padding的时候是不是懵了,——什么他娘的内边距,什么他娘的外边 ...

  10. Eclipse导入工程中文乱码问题

    此文引用自eclipse导入工程中文乱码问题,作者elleniou. 关于Eclipse导入工程中文乱码问题实在是一个非常令人头疼的,深感一定要彻底解决才算放心,故摘抄上文如下: eclipse之所以 ...