http://poj.org/problem?id=3468
在伸展树上打laz标记 和线段树略有不同 经过splay操作后 每个节点之下的子节点都是不断变化的 所以每个节点需要单独开一个变量记录本身的值
using namespace std;
struct node;
node *null;
struct node
{
    node *fa,*ch[2];
    ll val,sum,laz;
    int sz;
    void wipe()
    {
        fa=ch[0]=ch[1]=null;
        sz=1,val=sum=laz=0;
    }
    void setc(node *tmp,int d)
    {
        ch[d]=tmp;
        tmp->fa=this;
    }
    int getd()
    {
        return fa->ch[1]==this;
    }
    void pushup()
    {
        sz=ch[0]->sz+ch[1]->sz+1;
        sum=ch[0]->val+ch[0]->sum+ch[1]->val+ch[1]->sum;
    }
    void pushdown()
    {
        if(laz!=0)
        {
            ch[0]->val+=laz,ch[0]->sum+=(ch[0]->sz-1)*laz,ch[0]->laz+=laz;
            ch[1]->val+=laz,ch[1]->sum+=(ch[1]->sz-1)*laz,ch[1]->laz+=laz;
            laz=0;
        }
    }
};
node pool[100010];
node *root,*tail;
ll ary[100010];
int n,q;
void build(node *&cur,node *fa,int l,int r)
{
    int m;
    if(l>r) return;
    m=(l+r)/2;
    cur=tail++;
    cur->wipe();
    cur->fa=fa;
    cur->sz=1,cur->val=ary[m],cur->sum=0,cur->laz=0;
    build(cur->ch[0],cur,l,m-1);
    build(cur->ch[1],cur,m+1,r);
    cur->pushup();
}
void init()
{
    node *tmp;
    tail=pool;
    null=tail++;
    null->fa=null->ch[0]=null->ch[1]=null;
    null->sz=null->val=null->sum=null->laz=0;
    tmp=tail++;
    tmp->wipe();
    root=tmp;
    tmp=tail++;
    tmp->wipe();
    root->setc(tmp,1);
    build(root->ch[1]->ch[0],root->ch[1],1,n);
    root->ch[1]->ch[0]->pushup();
    root->ch[1]->pushup();
}
void rotate(node *cur)
{
    node *f,*ff;
    int c,cc;
    f=cur->fa,ff=cur->fa->fa;
    f->pushdown();
    cur->pushdown();
    c=cur->getd(),cc=f->getd();
    f->setc(cur->ch[!c],c);
    cur->setc(f,!c);
    if(ff->ch[cc]==f) ff->setc(cur,cc);
    else cur->fa=ff;
    f->pushup();
}
void splay(node *&root,node *tar,node *cur)
{
    while(cur->fa!=tar)
    {
        if(cur->fa->fa==tar) rotate(cur);
        else
        {
            cur->fa->fa->pushdown();
            cur->fa->pushdown();
            cur->pushdown();
            if(cur->getd()==cur->fa->getd()) rotate(cur->fa);
            else rotate(cur);
            rotate(cur);
        }
    }
    cur->pushup();
    if(tar==null) root=cur;
}
node *getkth(node *r,int k)
{
    node *cur;
    cur=r;
    cur->pushdown();
    while(cur->ch[0]->sz+1!=k)
    {
        if(cur->ch[0]->sz+1>k)
        {
            cur=cur->ch[0];
        }
        else
        {
            k-=(cur->ch[0]->sz+1);
            cur=cur->ch[1];
        }
        cur->pushdown();
    }
    return cur;
}
int main()
{
    int i,l,r,val;
    char op[10];
    scanf("%d%d",&n,&q);
    for(i=1;i<=n;i++) scanf("%lld",&ary[i]);
    init();
    while(q--)
    {
        scanf("%s",op);
        if(op[0]=='C')
        {
            scanf("%d%d%d",&l,&r,&val);
            splay(root,null,getkth(root,l));
            splay(root->ch[1],root,getkth(root,r+2));
            root->ch[1]->ch[0]->val+=val;
            root->ch[1]->ch[0]->sum+=(root->ch[1]->ch[0]->sz-1)*val;
            root->ch[1]->ch[0]->laz+=val;
        }
        else
        {
            scanf("%d%d",&l,&r);
            splay(root,null,getkth(root,l));
            splay(root->ch[1],root,getkth(root,r+2));
            printf("%lld\n",root->ch[1]->ch[0]->val+root->ch[1]->ch[0]->sum);
        }
    }
    return 0;
}
                










