poj 3468(线段树,splay tree)

来源:互联网 发布:51单片机da转换 编辑:程序博客网 时间:2024/05/17 18:04

点击打开链接


代码:

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <stack>#include <map>#include <set>#include <vector>#include <queue>#define mem(p,k) memset(p,k,sizeof(p));#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define inf 0x6fffffff#define LL long long#define MAX 100010using namespace std;int n;int root,tot,pre[MAX],ch[MAX][2],sz[MAX];LL  sum[MAX],key[MAX],num[MAX],col[MAX];void new_node(int &r,int fa,int k){    r=++tot;    sz[r]=1;    sum[r]=key[r]=k;    pre[r]=fa;    ch[r][1]=ch[r][0]=0;    col[r]=0;}void push_up(int rt){    sum[rt]=sum[ch[rt][0]]+sum[ch[rt][1]]+key[rt];//!!!!    sz[rt]=sz[ch[rt][0]]+sz[ch[rt][1]]+1;//!!!!}void update(int rt,LL k){    if(!rt)return;    col[rt]+=k;    key[rt]+=k;    sum[rt]+=sz[rt]*k;}void push_down(int rt){    if(col[rt]){        update(ch[rt][0],col[rt]);        update(ch[rt][1],col[rt]);        col[rt]=0;    }}void build(int &rt,int l,int r,int fa){    if(l>r)return;    int m=(l+r)>>1;    new_node(rt,fa,num[m]);    build(ch[rt][0],l,m-1,rt);    build(ch[rt][1],m+1,r,rt);    push_up(rt);//cout<<m<<"="<<sz[rt]<<endl;}void rotat(int rt,int k){    int y=pre[rt];    push_down(y);    push_down(rt);    pre[ch[rt][k]]=y;    ch[y][!k]=ch[rt][k];    if(pre[y]){        ch[pre[y]][ch[pre[y]][1]==y]=rt;    }    pre[rt]=pre[y];    pre[y]=rt;    ch[rt][k]=y;    push_up(y);}void splay(int rt,int goal){    push_down(rt);    while(pre[rt]!=goal){        int y=pre[rt];        if(pre[y]==goal){//单旋转            rotat(rt,ch[y][0]==rt);        }        else{            int k=ch[pre[y]][0]==y;            if(ch[y][k]==rt){//之字形                rotat(rt,!k);                rotat(rt,k);            }            else{//一字型                rotat(y,k);                rotat(rt,k);            }        }    }    push_up(rt);    if(goal==0)root=rt;}int get_th(int rt,int k){    push_down(rt);//cout<<k<<endl;    int t=sz[ch[rt][0]]+1;//if(cur++<5)cout<<sz[ch[rt][0]]<<endl;    if(t==k)return rt;    if(t>k) return get_th(ch[rt][0],k);    return get_th(ch[rt][1],k-t);}void add(int l,int r,int k){    splay(get_th(root,l),0);//cout<<f<<endl;    splay(get_th(root,r+2),root);    update(ch[ch[root][1]][0],k);    push_up(ch[root][1]);    push_up(root);}LL query(int l,int r){    splay(get_th(root,l),0);    splay(get_th(root,r+2),root);    return sum[ch[ch[root][1]][0]];}void init(){    for(int i=1;i<=n;i++)scanf("%lld",num+i);    root=tot=0;    sz[0]=ch[0][0]=ch[0][1]=pre[0]=sum[0]=col[0]=key[0]=0;    new_node(root,0,-1);    new_node(ch[root][1],root,-1);    build(ch[ch[root][1]][0],1,n,ch[root][1]);    push_up(ch[root][1]);//cout<<sz[ch[root][1]]<<endl;    push_up(root);}int main(){    int q;    cin>>n>>q;    init();    while(q--){        char c[2];        int l,r,k;        scanf("%s %d%d",&c,&l,&r);//cout<<l<<r;        if(c[0]=='C'){            scanf("%d",&k);            add(l,r,k);        }        else{            printf("%lld\n",query(l,r));        }    }    return 0;}



0 0
原创粉丝点击