B - 秋實大哥與花
Time Limit: 3000/1000MS (Java/Others) ??? Memory Limit: 65535/65535KB (Java/Others)
秋實大哥是一個儒雅之人,晝聽笙歌夜醉眠,若非月下即花前。
所以秋實大哥精心照料了很多花朵。現在所有的花朵排成了一行,每朵花有一個愉悅值。
秋實大哥每天要對著某一段連續的花朵歌唱,然后這些花朵的愉悅值都會增加一個相同的值v(v可能為負)。
同時他想知道每次他唱完歌后這一段連續的花朵的愉悅值總和是多少。
Input
第一行有一個整數n,表示花朵的總數目。
第二行包含n個整數ai,表示第i朵花初始的愉悅值。
第三行包含一個整數m,表示秋實大哥唱了m天的歌。
接下來m行,每行包含三個整數l?r?v,表示秋實大哥對著[l,r]這個區間內的花朵歌唱,每朵花的愉悅值增加了v。
1≤n,m,ai,|v|≤100000,1≤l≤r≤n。
Output
輸出共m行,第i行表示秋實大哥完成第i天的歌唱后,那一段花朵的愉悅值總和。
Sample input and output
Sample Input | Sample Output |
---|---|
3 0 0 0 3 1 2 1 1 2 -1 1 3 1 | 2 0 3 |
解題報告:
沒啥好說的,線段樹模板基礎題。。唯一需要注意的就是long long了.
當然我是使用的樹狀數組:
題目中操作屬于區間更新?-?區間查詢<查詢點也是區間嘛>類型,可使用樹狀數組來實現.
令C[i]為從1至i號花的共同更新之和.
首先考慮更新,add[l,r,v]?→?c[r]?+=?v?,?c[l-1]?-=v;
?Sum[x]?=?從?1?至?x?號花的value之和.
??Sum[x]?=?c[1]*1?+?c[2]*2?+?c[3]?*?3?.....?+?c[x]?*?x?+?(c[x+1]?+?....?C[n]?)?*x;
??????????= (segema)f(x)?+ (segema)g(x)?*?x;
??????????=?兩個樹狀數組,一個維護?c[i]*i?,一個維護c[i]
之后考慮區間查詢:
?Query(l?,?r)
?=?sum[r]?-?sum[l-1]
?
1 #include <iostream> 2 #include <cstring> 3 typedef long long ll; 4 using namespace std; 5 const int maxn = 1e5 + 50; 6 ll n; 7 ll f[maxn],g[maxn]; 8 9 10 inline ll lowbit(ll idx) 11 { 12 return idx & (-idx); 13 } 14 15 void updataf(ll idx,ll res) 16 { 17 if (!idx) 18 return; 19 while(idx <= n) 20 { 21 f[idx] += res; 22 idx += lowbit(idx); 23 } 24 } 25 26 void updatag(ll idx,ll res) 27 { 28 if (!idx) 29 return; 30 while(idx <= n) 31 { 32 g[idx] += res; 33 idx += lowbit(idx); 34 } 35 } 36 37 ll sumf(ll idx) 38 { 39 ll res = 0; 40 while(idx > 0) 41 { 42 res += f[idx]; 43 idx -= lowbit(idx); 44 } 45 return res; 46 } 47 48 ll sumg(ll idx) 49 { 50 ll res = 0; 51 while(idx > 0) 52 { 53 res += g[idx]; 54 idx -= lowbit(idx); 55 } 56 return res; 57 } 58 59 int main(int argc,char *argv[]) 60 { 61 ll m; 62 scanf("%lld%lld",&n,&m); 63 memset(f,0,sizeof(f)); 64 memset(g,0,sizeof(g)); 65 for(int j = 1 ; j <= n ; ++ j) 66 { 67 ll v; 68 scanf("%lld",&v); 69 updataf(j,v*j); 70 updataf(j-1,-v*(j-1)); 71 updatag(j,v); 72 updatag(j-1,-v); 73 } 74 while(m--) 75 { 76 ll i,j,v; 77 scanf("%lld%lld%lld",&i,&j,&v); 78 updataf(j,v*j); 79 updataf(i-1,-v*(i-1)); 80 updatag(j,v); 81 updatag(i-1,-v); 82 i--; 83 ll res1 = sumf(i) + i*(sumg(n)-sumg(i)); 84 ll res2 = sumf(j) + j*(sumg(n)-sumg(j)); 85 printf("%lld\n",res2 - res1); 86 } 87 return 0; 88 }
?
?