这题用线段树轻松解了,重新用树状数组解,关键点是区间更新。
公式推导如下:
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就好了。
/* 3468 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
#define lson l, mid, rt<<1
#define rson mid+1, r, rt<<1|1 typedef struct {
__int64 s, ss;
} node_t; const int maxn = 1e5+;
int a[maxn];
__int64 tot[maxn];
node_t nd[maxn];
int n, q; int lowest(int x) {
return -x & x;
} __int64 sum(int x) {
__int64 s = , ss = ;
int xx = x; while (x) {
s += nd[x].s;
ss += nd[x].ss;
x -= lowest(x);
} return (xx+) * s - ss;
} void update(int x, int delta) {
__int64 tmp = 1LL * x * delta; while (x <= n) {
nd[x].s += delta;
nd[x].ss += tmp;
x += lowest(x);
}
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif scanf("%d %d", &n, &q);
rep(i, , n+) {
scanf("%d", &a[i]);
tot[i] = tot[i-] + a[i];
} __int64 ans;
char op[];
int l, r, d; while (q--) {
scanf("%s %d %d", op, &l, &r);
if (op[] == 'Q') {
ans = tot[r] - tot[l-] + sum(r) - sum(l-);
printf("%I64d\n", ans);
} else {
scanf("%d", &d);
update(l, d);
update(r+, -d);
}
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}
数据发生器。
from copy import deepcopy
from random import randint, shuffle
import shutil
import string def GenDataIn():
with open("data.in", "w") as fout:
t = 1
bound = 10**3
# fout.write("%d\n" % (t))
for tt in xrange(t):
n = randint(100, 200)
q = randint(100, 200)
fout.write("%d %d\n" % (n, q))
L = []
for i in xrange(n):
x = randint(1, bound)
L.append(x)
fout.write(" ".join(map(str, L)) + "\n")
for i in xrange(q):
op = randint(0, 1)
if op:
l = randint(1, n)
r = randint(l, n)
k = randint(1, bound)
fout.write("C %d %d %d\n" % (l, r, k))
else:
l = randint(1, n)
r = randint(l, n)
fout.write("Q %d %d\n" % (l, r)) def MovDataIn():
desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
shutil.copyfile("data.in", desFileName) if __name__ == "__main__":
GenDataIn()
MovDataIn()