zoukankan      html  css  js  c++  java
  • [模版]平衡树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("
    %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
    ",ask(x,y));
    145     }
    146     return 0;
    147 }
  • 相关阅读:
    HDU
    POJ
    POJ
    POJ
    POJ
    POJ
    POJ
    SPFA算法——最短路径
    POJ1251 Jungle Roads Kruskal+scanf输入小技巧
    MongoDB--关于数据库及选择MongoDB的原因
  • 原文地址:https://www.cnblogs.com/Yuzao/p/6796299.html
Copyright © 2011-2022 走看看