http://poj.org/problem?id=3468
寫完後發現用指標的速度比數組快了一秒。。。。。
等有空把那個維修數列也寫一寫試一下,不知道能跑多快
貼一下一個下午的成果吧,總感覺代碼量上還可以精簡,,,,求路過的神牛指導啊
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;typedef long long lld;#define L x->c[0]#define R x->c[1]#define KT root->c[1]->c[0]const int maxn = 100010;struct node {struct node *c[2] , *fa;int id ;int sz;int val;int add;lld sum;void down(){if(add) {if(c[0]) {c[0]->val += add;c[0]->add += add;c[0]->sum += (lld)add * c[0]->sz;} if(c[1]) {c[1]->val += add;c[1]->add += add;c[1]->sum += (lld)add * c[1]->sz;}add = 0;}}void up() {sz = c[0]->sz + c[1]->sz + 1;sum= val + c[0]->sum + c[1]->sum;}}*root,NODE[maxn],*null=&NODE[0];int num[maxn] , n , top; struct SplayTree{void Rotate(node *x,int f) {node *y = x->fa;y->down(); x->down();y->c[!f] = x->c[f];x->c[f]->fa = y;x->fa = y->fa;if(x->fa != null) y->fa->c[ y->fa->c[1] == y ] = x; x->c[f] = y;y->fa = x;y->up();}void Splay(node *x,node *goal) {x->down();while(x->fa != goal) {if(x->fa->fa == goal) Rotate(x,x->fa->c[0] == x);else {node *y = x->fa , *z = y->fa;int f = (z->c[0] == y);y->c[f]==x ? Rotate(x,!f) :Rotate(y,f);Rotate(x,f);}}x->up();if(goal == null) root = x;}void RTO(int k,node *goal) {node *x = root;x->down();while(L->sz + 1 != k) {if(k < L->sz + 1) x = L;else{k -= L->sz + 1;x = R;}x->down();}Splay(x,goal);}node *new_node(node *fa,int v) {node *x=&NODE[++top];x->id = top;x->c[0] = x->c[1] = null;x->sz = 1;x->val = x->sum = v;x->add = 0;x->fa = fa;return x;}void build(node* &x,int l,int r,node *fa) {if(l > r) return ;int m = l + r>>1;x = new_node(fa,num[m]);build(x->c[0],l,m-1,x);build(x->c[1],m+1,r,x);x->up();}void vist(node *x) {if(x!=null){printf("節點:%2d : 左兒子: %2d 右兒子: %2d sz: %2d sum: %2lld\n",x->id,x->c[0]->id,x->c[1]->id,x->sz,x->sum);vist(x->c[0]);vist(x->c[1]);}}void init(int n) {top = 0;null->id = 0;null->c[0] = null->c[1] = null->fa = NULL;null->sz = null->add = null->sum = null->val = 0;root = new_node(null,-1);root->c[1] = new_node(root,-1);root->sz = 2;for(int i = 1; i <= n; i++) scanf("%d",&num[i]);build(KT,1,n,root->c[1]);root->c[1]->up(); root->up();}void update(){int l ,r , c;scanf("%d%d%d",&l,&r,&c);RTO(l,null);RTO(r+2,root);KT->add += c;KT->val += c;KT->sum += (lld)c * KT->sz;}void query() {int l ,r ;scanf("%d%d",&l,&r);RTO(l,null);RTO(r+2,root);printf("%I64d\n",KT->sum);}}spt;int main() {char op[10];int m;scanf("%d%d",&n,&m);spt.init(n);for(int i=0;i<m;i++) {scanf("%s",op);if(op[0] == 'Q')spt.query();else spt.update();}return 0;}