[模版]平衡树splay2

题目描述

1. 加入:一个新的成员加入同好会,我会分配给他一个没有使用的id,并且询问他的兴趣值val。
2. 修改:id在区间[a,b]内的成员,兴趣值同时改变k,k有可能是负数,表示他们失去了对同好会的兴趣。
3. 退出:id在区间[a,b]内的成员要退出同好会,虽说是区间,也有可能只有1个人。
4. 询问:老师会问我在区间[a,b]内的成员总的兴趣值。

输入

第1行:1个正整数n,表示操作数量,100≤n≤200,000
第2..n+1行:可能包含下面4种规则:
1个字母'I',紧接着2个数字id,val,表示一个编号为id的新成员加入,其兴趣值为val,1≤id≤100,000,000,1≤val≤10,000,000,保证在团队中的每个人id都不相同。
1个字母'Q',紧接着2个数字a,b。表示询问团队中id在区间[a,b]的所有成员总兴趣值,保证区间内至少有一个成员,结果有可能超过int的范围。
1个字母'M',紧接着3个数字a,b,d,表示将团队中id在区间[a,b]的成员兴趣值都改变d,其中d有可能为负数。保证操作之后每个成员的兴趣值仍然在0~10,000,000。
1个字母'D',紧接着2个数字a,b,表示将团队中id在区间[a,b]的成员除去。
注意有可能出现一个id为1的成员加入团队,被除去之后,又有一个新的id为1的成员加入团队的情况。

输出

若干行:每行1个整数,表示针对询问的回答,保证一定有合法的解

样例输入

9 I 1 1 I 2 2 I 3 3 Q 1 3 M 1 2 2 Q 1 3 D 2 3 I 4 2 Q 1 4

样例输出

6 10 5
 
需注意的细节:
1.Delet Add rotate等地方要updata
2.insert rotate处标记要下移
3.size*mark时要转(Long Long)
4.关键是时时刻刻都要先pushdown再updata 和 rotate 不然会出错
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 #include<cstdlib>
  7 #include<ctime>
  8 using namespace std;
  9 typedef long long ll;
 10 const int N=200005,INF=10000001;
 11 struct node
 12 {
 13     node *child[2],*fa;
 14     int x,mark,size,val;long long sum;
 15 }a[N];
 16 node *pos=a,*root,*newone;
 17 void check(node *r);
 18 void updata(node *&r)
 19 {
 20     if(r){
 21         r->sum=(r->child[0]?r->child[0]->sum:0)+(r->child[1]?r->child[1]->sum:0)+r->val;
 22         r->size=(r->child[0]?r->child[0]->size:0)+(r->child[1]?r->child[1]->size:0)+1;
 23     }
 24 }
 25 void pushdown(node *&r)
 26 {
 27     if(!r || !r->mark)return ;
 28     if(r->child[0])r->child[0]->mark+=r->mark,r->child[0]->sum+=(ll)r->mark*r->child[0]->size,r->child[0]->val+=r->mark;
 29     if(r->child[1])r->child[1]->mark+=r->mark,r->child[1]->sum+=(ll)r->mark*r->child[1]->size,r->child[1]->val+=r->mark;
 30     updata(r);
 31     r->mark=0;
 32 }
 33 void rotate(node *&r,bool t)//0left 1right 
 34 {
 35     node *y=r->fa;
 36     pushdown(y);
 37     pushdown(r);
 38     y->child[!t]=r->child[t];
 39     if(r->child[t])r->child[t]->fa=y;
 40     if(y->fa)y->fa->child[y->fa->child[1]==y]=r;
 41     r->fa=y->fa;
 42     r->child[t]=y;
 43     y->fa=r;
 44     updata(r);
 45     updata(y);
 46     updata(r->fa);
 47 }
 48 void splay(node *r,node *g)
 49 {
 50     while(r->fa!=g)
 51     {
 52         if(r->fa->fa==g)rotate(r,r->fa->child[0]==r);
 53         else
 54         {
 55             node *y=r->fa;
 56             bool t=y->fa->child[0]==y;
 57             if(y->child[t]==r)rotate(r,!t);
 58             else rotate(y,t);
 59             rotate(r,t);
 60         }
 61     }
 62     if(g==NULL)root=r;
 63 }
 64 void newnode(node *&r,int key,int val,node *fa)
 65 {
 66     r=pos++;
 67     r->fa=fa;
 68     r->child[0]=r->child[1]=NULL;
 69     r->x=key;r->val=val;r->mark=0;r->size=1;r->sum=val;
 70 }
 71 void insert(node *&r,int key,int val,node *fa)
 72 {
 73     if(r==NULL){
 74         newnode(r,key,val,fa);
 75         splay(r,NULL);
 76         return ;
 77     }
 78     else {
 79         pushdown(r);
 80         insert(r->child[key>r->x],key,val,r); 
 81     }    
 82 }
 83 node *pre,*nxt;
 84 void getpre(node *r,int key)
 85 {
 86     if(r==NULL)return ;
 87     if(r->x>=key)getpre(r->child[0],key);
 88     else pre=r,getpre(r->child[1],key);
 89 }
 90 void getnext(node *r,int key)
 91 {
 92     if(r==NULL)return ;
 93     if(r->x<=key)getnext(r->child[1],key);
 94     else nxt=r,getnext(r->child[0],key);
 95 }
 96 void work(int l,int r)
 97 {
 98     getpre(root,l);getnext(root,r);
 99     splay(pre,NULL);splay(nxt,pre);
100     updata(root->child[1]);updata(root);
101 }
102 void Delet(int l,int r)
103 {
104     work(l,r);
105     root->child[1]->child[0]=NULL;
106     updata(root->child[1]);updata(root);
107 }
108 void add(int l,int r,int to)
109 {
110     work(l,r);
111     root->child[1]->child[0]->mark+=to;
112     root->child[1]->child[0]->sum+=(ll)to*root->child[1]->child[0]->size;
113     root->child[1]->child[0]->val+=to;
114     updata(root->child[1]);updata(root);
115 }
116 long long ask(int l,int r)
117 {
118     work(l,r);
119     node *y=root->child[1]->child[0];
120     return y==NULL?0:y->sum;
121 }
122 void haha()
123 {
124    insert(root,-INF,0,NULL);
125    insert(root,INF,0,NULL);
126 }
127 int main()
128 {
129     freopen("pp.in","r",stdin);
130     freopen("pp.out","w",stdout);
131     haha();
132     int n;
133     char ch;int x,y,z;
134     scanf("%d",&n);
135     while(n--)
136     {
137         scanf("\n%c%d%d",&ch,&x,&y);
138         if(ch=='I')insert(root,x,y,NULL);
139         if(ch=='D')Delet(x,y);
140         if(ch=='M'){
141             scanf("%d",&z);
142             add(x,y,z);
143         }
144         if(ch=='Q')printf("%lld\n",ask(x,y));
145     }
146     return 0;
147 }

 

posted @ 2017-05-02 15:27  PIPIBoss  阅读(330)  评论(3编辑  收藏  举报