这次写的是接着上次的线段树写的,上次只写了线段树的单点修改,区间求最大值。
然而之后又继续学习了线段树的区间修改以及区间求和的问题
然后呢,这次肯定就是关于;
线段树的区间修改,区间求最大值:
学完之后感觉是和之前的那些差不多,都是一个思想,只不过对于一个区间的修改,也就是区间内每一个值都需要加上相同的值,时间上也就是区间修改的总的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; }