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; }