这题用线段树轻松解了,重新用树状数组解,关键点是区间更新。
公式推导如下:
sum[x] = org_sum[x] + delta[1]*x + delta[2]*(x-1) + delta[x]*1
= org_sum[x] + Sigma(delta[1..x]) * (x+1) - Sigma(delta[i]*i)
树状数组增加两个结点信息分别存delta[i] 和 delta[i] * i就好了。
1 /* 3468 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string> 5 #include <map> 6 #include <queue> 7 #include <set> 8 #include <stack> 9 #include <vector> 10 #include <deque> 11 #include <algorithm> 12 #include <cstdio> 13 #include <cmath> 14 #include <ctime> 15 #include <cstring> 16 #include <climits> 17 #include <cctype> 18 #include <cassert> 19 #include <functional> 20 #include <iterator> 21 #include <iomanip> 22 using namespace std; 23 //#pragma comment(linker,"/STACK:102400000,1024000") 24 25 #define sti set<int> 26 #define stpii set<pair<int, int> > 27 #define mpii map<int,int> 28 #define vi vector<int> 29 #define pii pair<int,int> 30 #define vpii vector<pair<int,int> > 31 #define rep(i, a, n) for (int i=a;i<n;++i) 32 #define per(i, a, n) for (int i=n-1;i>=a;--i) 33 #define clr clear 34 #define pb push_back 35 #define mp make_pair 36 #define fir first 37 #define sec second 38 #define all(x) (x).begin(),(x).end() 39 #define SZ(x) ((int)(x).size()) 40 #define lson l, mid, rt<<1 41 #define rson mid+1, r, rt<<1|1 42 43 typedef struct { 44 __int64 s, ss; 45 } node_t; 46 47 const int maxn = 1e5+5; 48 int a[maxn]; 49 __int64 tot[maxn]; 50 node_t nd[maxn]; 51 int n, q; 52 53 int lowest(int x) { 54 return -x & x; 55 } 56 57 __int64 sum(int x) { 58 __int64 s = 0, ss = 0; 59 int xx = x; 60 61 while (x) { 62 s += nd[x].s; 63 ss += nd[x].ss; 64 x -= lowest(x); 65 } 66 67 return (xx+1) * s - ss; 68 } 69 70 void update(int x, int delta) { 71 __int64 tmp = 1LL * x * delta; 72 73 while (x <= n) { 74 nd[x].s += delta; 75 nd[x].ss += tmp; 76 x += lowest(x); 77 } 78 } 79 80 int main() { 81 ios::sync_with_stdio(false); 82 #ifndef ONLINE_JUDGE 83 freopen("data.in", "r", stdin); 84 freopen("data.out", "w", stdout); 85 #endif 86 87 scanf("%d %d", &n, &q); 88 rep(i, 1, n+1) { 89 scanf("%d", &a[i]); 90 tot[i] = tot[i-1] + a[i]; 91 } 92 93 __int64 ans; 94 char op[4]; 95 int l, r, d; 96 97 while (q--) { 98 scanf("%s %d %d", op, &l, &r); 99 if (op[0] == 'Q') { 100 ans = tot[r] - tot[l-1] + sum(r) - sum(l-1); 101 printf("%I64d\n", ans); 102 } else { 103 scanf("%d", &d); 104 update(l, d); 105 update(r+1, -d); 106 } 107 } 108 109 #ifndef ONLINE_JUDGE 110 printf("time = %d.\n", (int)clock()); 111 #endif 112 113 return 0; 114 }
数据发生器。
1 from copy import deepcopy 2 from random import randint, shuffle 3 import shutil 4 import string 5 6 7 def GenDataIn(): 8 with open("data.in", "w") as fout: 9 t = 1 10 bound = 10**3 11 # fout.write("%d\n" % (t)) 12 for tt in xrange(t): 13 n = randint(100, 200) 14 q = randint(100, 200) 15 fout.write("%d %d\n" % (n, q)) 16 L = [] 17 for i in xrange(n): 18 x = randint(1, bound) 19 L.append(x) 20 fout.write(" ".join(map(str, L)) + "\n") 21 for i in xrange(q): 22 op = randint(0, 1) 23 if op: 24 l = randint(1, n) 25 r = randint(l, n) 26 k = randint(1, bound) 27 fout.write("C %d %d %d\n" % (l, r, k)) 28 else: 29 l = randint(1, n) 30 r = randint(l, n) 31 fout.write("Q %d %d\n" % (l, r)) 32 33 34 def MovDataIn(): 35 desFileName = "F:\eclipse_prj\workspace\hdoj\data.in" 36 shutil.copyfile("data.in", desFileName) 37 38 39 if __name__ == "__main__": 40 GenDataIn() 41 MovDataIn()