ccnu-线段树-简单的区间更新(三题)
题目一: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-线段树-简单的区间更新(三题)的更多相关文章
- HDOJ--4893--Wow! Such Sequence!【线段树+单点、区间更新】
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 题意:给你一个长度n的数列,初始都为0.有三种操作,第一种给第k个位置的数加d.另外一种是查询区间 ...
- HDU4893【线段树单点、区间更新】
题目链接[http://acm.hdu.edu.cn/showproblem.php?pid=4893] 题意:输入n.q.表示有n个数,初始化默认这n个数都为零,有q次操作,操作种类分为三种:1.输 ...
- codevs 1082 线段树练习 3 区间更新+延迟标记
题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 Input Description 第一行一个正整数n,接下 ...
- codevs 1081 线段树练习 2 区间更新 单点查询 无lazy
题目描述 Description 给你N个数,有两种操作 1:给区间[a,b]的所有数都增加X 2:询问第i个数是什么? 输入描述 Input Description 第一行一个正整数n,接下来n行n ...
- 洛谷 P3373:【模板】线段树 2(区间更新)
题目描述 如题,已知一个数列,你需要进行下面三种操作: 1.将某区间每一个数乘上x 2.将某区间每一个数加上x 3.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含三个整数N.M.P,分别 ...
- HDU 3577Fast Arrangement(线段树模板之区间增减更新 区间求和查询)
Fast Arrangement Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- POJ 3468 A Simple Problem with Integers(线段树模板之区间增减更新 区间求和查询)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 140120 ...
- Codeforces295A - Greg and Array(线段树的成段更新)
题目大意 给定一个序列a[1],a[2]--a[n] 接下来给出m种操作,每种操作是以下形式的: l r d 表示把区间[l,r]内的每一个数都加上一个值d 之后有k个操作,每个操作是以下形式的: x ...
- 线段树简单入门 (含普通线段树, zkw线段树, 主席树)
线段树简单入门 递归版线段树 线段树的定义 线段树, 顾名思义, 就是每个节点表示一个区间. 线段树通常维护一些区间的值, 例如区间和. 比如, 上图 \([2, 5]\) 区间的和, 为以下区间的和 ...
随机推荐
- CSS水平导航条和纵向导航条
问题描述: 使用CSS制作水平导航条和纵向导航条 问题解决: (1)水平导航条 1.1 效果预览: 1.2 ...
- Memcached常用命令及使用说明
一.存储命令 存储命令的格式: 1 2 <command name> <key> <flags> <exptime> <bytes> < ...
- 【BZOJ】【1034】【ZJOI2008】泡泡堂BNB
贪心 类似田忌赛马策略的一个贪心= = 随便YY了一个做法居然A了…… 简单来说就是先强对强,弱对弱,能赢就赢,不能赢就让弱的那个去对强的那个,剩下的人继续依次捉对比赛(继续刚刚的策略),现在人数还是 ...
- 【BZOJ】【1018】【SHOI2008】堵塞的交通traffic
线段树 这题的线段树+分类讨论蛮神奇的……我以前学的线段树简直就是渣渣QAQ 看了下ydc题解里的思想>_>用线段树维护连通性!那么就自己写吧……每个节点表示一段区间的连通性(我的叶子节点 ...
- 【BZOJ】【1003】【ZJOI2006】物流运输trans
最短路/DP 这题数据规模并不大!!这是重点……… 所以直接暴力DP就好了:f[i]表示前 i 天的最小花费,则有$f[i]=min\{f[j]+cost[j+1][i]+k\} (0\leq j \ ...
- 【bzoj1010】[HNOI2008]玩具装箱toy
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 9281 Solved: 3719[Submit][St ...
- linux 配置ssh免密码登录
1.确保主机名唯一 主机名修改方法: a.修改/etc/sysconfig/network,HOSTNAME=想要设置的主机名称 b.修改/etc/hosts,127.0.0.1 localhos ...
- codeforces #232 div2 解题报告
A:简单题:我们可以把点换成段处理,然后枚举段看是否被霸占了: #include<iostream> #include<]; ]=; ;i<=n;i++) { ...
- Telnet、FTP、SSH、SFTP、SCP
[Telnet]著名的终端访问协议,传统的网络服务程序,如FTP.POP和Telnet,其本质上都是不安全的:因为它们在网络上用明文传送数据.用户帐号和用户口令. [telnet命令]telnet h ...
- 深入理解jQuery的Event机制
jQuery的Event模块非常强大.其功能远远比原生事件监听器强大许多,对同一个元素的监听只用一个eventListener,内部则是一个强大的观察者,根据匹配事件类型触发相应回调.jQuery不仅 ...