这次写的是接着上次的线段树写的,上次只写了线段树的单点修改,区间求最大值。
然而之后又继续学习了线段树的区间修改以及区间求和的问题
然后呢,这次肯定就是关于;
线段树的区间修改,区间求最大值:
学完之后感觉是和之前的那些差不多,都是一个思想,只不过对于一个区间的修改,也就是区间内每一个值都需要加上相同的值,时间上也就是区间修改的总的sum和,就是区间内元素的个数乘上add数组的值, add数组保存的是在某个区间要对没个区间元素的增加值。(大体上的思路 都是 修改之后通过递归和二分的思想去维护每一个区间)。
题目链接 :点击打开链接
这也是一个纯模版题,只要会模版就可以AC,哈哈
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
#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
#define lson ri<<1,l,m //这个是我在网上学的一个小技巧
#define rson ri<<1|1,m+1,r
ll sum[maxn<<2], add[maxn<<2];
struct Node {
int left ,right;
int mid (){
return (left + right)>>1;
}
}tree[maxn<<2];
void PushUp (int ri){
sum[ri] = sum[ri<<1] + sum[ri<<1|1]; // sum[ri<<1|1] 相当于sum[(ri<<1)+1]
}
void PushDown (int ri, int m){
if (add[ri]){
add[ri<<1] += add[ri];
add[ri<<1|1] += add[ri];
sum[ri<<1] += add[ri] * (m-(m>>1));
sum[ri<<1|1] += add[ri] *(m>>1);
add[ri] = 0;
}
}
void build (int ri, int l, int r){
//cout << "text\n";
tree[ri].left = l;
tree[ri].right = r;
add[ri] = 0;
if (l == r){
//cin >> sum[ri];
scanf("%I64d",&sum[ri]);
return ;
}
int m = tree[ri].mid();
build (lson);
build (rson);
PushUp (ri);
}
void Update (int key,int l, int r, int ri){
if (tree[ri].left == l && tree[ri].right == r){
add[ri] += key;
sum[ri] +=(ll) key * (r - l + 1);
return ;
}
if (tree[ri].left == tree[ri].right) return ;
PushDown(ri,tree[ri].right - tree[ri].left + 1);
int m = tree[ri].mid();
if (r <= m){
Update (key,l,r,ri<<1);
}
else if (l > m){
Update (key, l, r, ri <<1|1);
}
else{
Update (key,l, m , ri<<1);
Update (key, m+1, r, ri<<1|1);
}
PushUp (ri);
}
ll search (int l, int r, int ri){
if (tree[ri].left == l && tree[ri].right == r){
return sum[ri];
}
PushDown (ri, tree[ri].right - tree[ri].left + 1);
int m = tree[ri].mid();
ll res = 0;
if (r <= m){
res += search (l, r, ri<<1);
}
else if (l > m){
res += search (l, r, ri<<1|1);
}
else{
res += search (l,m,ri<<1);
res += search (m+1, r, ri<<1|1);
}
return res;
}
int main (){
//ios::sync_with_stdio(false);
int n, m;
while (~scanf("%d%d",&n,&m)){
build (1, 1, n);
//cout << "text\n";
while (m--){
//cout << "text\n";
char ch[2];
int a,b,c;
//cin >> ch;
scanf("%s",ch);
if (ch[0] == 'Q'){
// cin >>a >> b;
// cout << search (a,b,1) <<endl;
scanf("%d%d",&a,&b);
printf("%I64d\n",search(a,b,1));
}
else{
//cin >> a >> b >> c;
scanf("%d%d%d",&a,&b,&c);
Update (c, a, b, 1);
}
}
}
return 0;
}