喵哈哈村的种花魔法(线段树的区间更新)
Posted starry
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了喵哈哈村的种花魔法(线段树的区间更新)相关的知识,希望对你有一定的参考价值。
喵哈哈村有一个谷歌廖,谷歌廖特别喜欢种花。
而且谷歌廖最神奇的就是,他会施展一种种花魔法,会使得一定区间的花儿,长高k厘米。
在谷歌廖施展若干次魔法之后,好奇的沈宝宝想知道,每朵花儿的高度是多少。
第一行两个整数n,m,分别表示花儿的数量,和谷歌廖施展种花魔法的次数。
第二行n个整数a[i],表示花儿一开始的高度为a[i]厘米。
接下来m行,每行三个整数l,r,k。表示谷歌廖使得区间[l,r]的花儿长高了k厘米。
1<=n,m<=100000
1<=a[i],k<=100000
1<=l<=r<=100000
输出n个整数,即输出每朵花儿在施展魔法之后的高度。
复制
3 1 1 2 3 1 2 5
6 7 3
复制
3 2 1 2 3 1 3 2 1 2 5
8 9 5
这题是线段树区间更新问题
以下贴出常规写法,以及大佬的写法。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define ll long long 5 #define lson l, m, rt<<1 6 #define rson m+1, r, rt<<1|1 7 const int maxn = 1e6+10; 8 using namespace std; 9 ll flo[maxn<<2]; 10 void PushUP(int rt){ 11 flo[rt] = flo[rt<<1] + flo[rt<<1|1]; 12 } 13 void build(int l, int r, int rt){ 14 if(l == r){ 15 scanf("%lld",&flo[rt]); 16 return; 17 } 18 int m = (l + r) >> 1; 19 build(lson); 20 build(rson); 21 } 22 void update(int L, int R, ll add, int l, int r, int rt){ 23 if(L <= l && r <= R){ 24 flo[rt] += add; 25 return; 26 } 27 int m = (l + r) >> 1; 28 if(m >= L) update(L, R, add, lson); 29 if(m < R) update(L, R, add, rson); 30 //PushUP(rt); 31 } 32 void query(int l, int r, int rt, ll k){ 33 if(l == r){ 34 printf("%lld ",flo[rt]+k); 35 return; 36 } 37 int m = (l + r) >> 1; 38 if(m >= l) query(lson,k+flo[rt]); 39 if(m < r) query(rson,k+flo[rt]); 40 } 41 int main() 42 { 43 int n, m; 44 while(cin>>n>>m){ 45 memset(flo, 0, sizeof(flo)); 46 build(1, n, 1); 47 ll a, b, c; 48 while(m--){ 49 scanf("%d%d%d",&a,&b,&c); 50 update(a, b, c, 1, n, 1); 51 } 52 query(1, n, 1, 0); 53 printf("\n"); 54 } 55 return 0; 56 }
大佬的代码好牛逼,简单易懂。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const int maxn = 1e5+10; 5 ll a[maxn], b[maxn]; 6 int main(){ 7 int n, m; 8 while(cin>>n>>m){ 9 memset(b, 0, sizeof(b)); 10 for(int i = 1; i <= n; i++){ 11 scanf("%lld",&a[i]); 12 } 13 for(int i = 1; i <= m; i++){ 14 ll l, r, val; 15 scanf("%d%d%lld",&l,&r,&val); 16 b[l] += val; 17 b[r+1] -= val; 18 } 19 ll sum = 0; 20 for(int i = 1; i <= n; i++){ 21 sum += b[i]; 22 a[i] += sum; 23 } 24 for(int i = 1; i <= n; i++){ 25 printf("%lld ",a[i]); 26 } 27 printf("\n"); 28 } 29 return 0; 30 }
以上是关于喵哈哈村的种花魔法(线段树的区间更新)的主要内容,如果未能解决你的问题,请参考以下文章