PKU/POJ 3468
线段树水题- -囧。。每天做水题。
看了discuss里面有人用树状数组过了这个题,我也试了一下,简单的树状数组tle了,bit的扩展也实在不会,太菜b了--,最后还是放弃了。线段树实现也不是很复杂,无非是一些细节的地方吧。正式比赛绝对碰不上这个层次的水题了吧。话说比赛遇到的线段树都是……哎,泪狂奔啊= =!
虽然贴代码是一个非常掉rp而且招人bs的习惯,我还是把代码贴一下吧>_<
#include <iostream> #include <string.h> #include <algorithm> #include <fstream> #include <string> using namespace std; const int N = 1048756; const int MAX = 100050; const int inf = 0x3f3f3f3f; struct Node{ __int64 sum, tot; int start, end; }d[N<<1]; __int64 num[MAX]; void init(){ for (int i = 0; i < (N<<1); i++){ d[i].start = inf; d[i].end = -inf; d[i].sum = d[i].tot = 0; } } inline int leftchild(int p){ return (p<<1); } inline int rightchild(int p){ return (p<<1) + 1; } inline int parent(int c){ return (c>>1); } inline int getnode(int i){ return N + i - 1; } void update(int p){ int l = leftchild(p); int r = rightchild(p); d[p].sum = d[l].sum + d[r].sum; d[p].start = min(d[l].start,d[r].start); d[p].end = max(d[r].end,d[l].end); } void insert(int i){ int k = getnode(i); d[k].sum = num[i]; d[k].start = d[k].end = i; int cur = parent(k); while (cur > 0){ update(cur); cur = parent(cur); } } __int64 search(int a, int b, int cur){ if (d[cur].start==a&&d[cur].end==b){ return (d[cur].sum + (b-a+1)*d[cur].tot); } int l = leftchild(cur); int r = rightchild(cur); __int64 temp = d[cur].tot; d[cur].sum += (d[cur].end-d[cur].start+1)*d[cur].tot; d[cur].tot = 0; d[l].tot += temp; d[r].tot += temp; if (a>=d[l].start&&b<=d[l].end) return search(a,b,l); else if (a>=d[r].start&&b<=d[r].end) return search(a,b,r); else { return search(a,d[l].end,l) + search(d[r].start, b, r); } } void change(int a, int b, __int64 value, int cur) { if (d[cur].start==a&&d[cur].end==b){ d[cur].tot += value; return; } int l = leftchild(cur); int r = rightchild(cur); d[cur].sum += (b-a+1)*value; if (a>=d[l].start&&b<=d[l].end) change(a,b,value,l); else if (a>=d[r].start&&b<=d[r].end) change(a,b,value,r); else { change(a,d[l].end,value,l); change(d[r].start,b,value,r); } return; } int main() { int n, q, a, b, i; __int64 t; char ch; while (scanf("%d%d", &n, &q) != EOF) { init(); for (i = 1; i <= n; i++){ scanf("%I64d", &num[i]); insert(i); } cin.get(); for (i = 0; i < q; i++){ scanf("%c", &ch); if (ch == 'Q'){ scanf("%d%d", &a, &b); printf("%I64d\n", search(a,b,1)); } if (ch == 'C'){ scanf("%d%d%I64d", &a, &b, &t); change(a, b, t, 1); } cin.get(); } } return 0; }