Poj1468【线段树】
2015-08-18 11:23
204 查看
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
Sample Output
Hint
The sums may exceed the range of 32-bit integers.
Source
POJ Monthly--2007.11.25, Yang Yi
题意:给出一段区间,每个点都有一个值,共有2种操作,一种是将区间i~j内的值全部加上c,其次是查询区间i~j的和。
思路:标准的线段树模板题,但是这里要用上延迟更新避免超时。
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
POJ Monthly--2007.11.25, Yang Yi
#include<stdio.h> #include<string.h> #define Min -10010 __int64 segtree[400000], a[100010], mark[400000]; void build(int l , int r, int id) { mark[id] = 0; if(l == r) { segtree[id] = a[l]; return ; } int mid = (l+r)>>1; build(l, mid, id<<1); build(mid+1, r, id<<1|1); segtree[id] = segtree[id<<1] + segtree[id<<1|1]; } void Pushdown(int id, int l, int r) { if(mark[id]) { mark[id<<1] += mark[id]; mark[id<<1|1] += mark[id]; int mid = (l+r)>>1; segtree[id<<1] += (mark[id] * (mid - l + 1) ); segtree[id<<1|1] += ( mark[id] * (r - mid) ); mark[id] = 0; } } __int64 query(int l, int r, int id, int L, int R) { if(L <= l && r <= R) { return segtree[id]; } Pushdown(id, l, r); int mid = (l+r)>>1; __int64 sum = 0; if(L <= mid) sum += query(l, mid, id<<1, L, R); if(R >= mid +1) sum += query(mid+1, r, id<<1|1, L, R); return sum; } void update(int l, int r, int id, int left, int right, int cnt) { if(left <= l && r <= right) { mark[id] += cnt; segtree[id] += (cnt * (r-l+1) ); return ; } Pushdown(id, l, r); int mid = (l+r)>>1; if(left <= mid) update(l, mid, id<<1, left, right, cnt); if(right >= mid+1) update(mid+1, r, id<<1|1, left, right, cnt); segtree[id] = segtree[id<<1] + segtree[id<<1|1]; } int main() { int i, j, k, n, m; scanf("%d%d", &n, &m); for(i = 1; i <= n; ++i) scanf("%I64d", &a[i]); build(1, n, 1); char s[10]; for(i = 0; i < m; ++i) { scanf("%s", s); if(strcmp(s, "Q") == 0) { int x, y; scanf("%d%d", &x, &y); printf("%I64d\n", query(1, n, 1, x, y) ); } else { int x, y, z; scanf("%d%d%d", &x, &y, &z); update(1, n, 1, x, y, z); } } return 0; }
题意:给出一段区间,每个点都有一个值,共有2种操作,一种是将区间i~j内的值全部加上c,其次是查询区间i~j的和。
思路:标准的线段树模板题,但是这里要用上延迟更新避免超时。
相关文章推荐
- js中==和===的区别
- 【Python】Windows平台下Python、Pydev连接Mysql数据库
- 在CentOS6.5搭建LAMP环境
- 系统相册和拍照
- cocos2d-js添加百通广告(通过jsb反射机制)
- 【appium】根据xpath定位元素
- C#统计C、C++及C#程序代码行数的方法
- 圆圈中最后剩下的数字
- html切换面板
- qt 程序用外部程序打开文件
- Swift-初学
- 神经网络该如何调参
- Android开发之Viewpager与TextView结合使用时不能滑动的问题
- 解决C语言中生成的EXE文件执行后窗口消失方法
- sql存储过程规范极其用应
- js 开启video全屏模式
- PHP高效率写法(详解原因)
- java对象转化为JSON格式
- android jni 打印信息到logcat
- 图片缩放与旋转