cogs 347 地震 splay

链接:http://cogs.pro/cogs/problem/problem.php?pid=347

题意:不断维护一个区间,要求支持的操作有:删除区间、插入区间、区间加减、查询区间最大值。

看到这个题我们直接想到splay。还是熟悉的老方法,事先建两个节点,每一次操作,不管属于任何一种操作,先将区间的右端点转到右儿子,左端点转到根节点3号孙子,即右儿子的左儿子处。

1、区间加减:直接修改,延迟标记。

2、区间删除:直接扔掉左边界对应节点即可。

3、查询:基本操作。

4、插入区间:首先找到该区间位置,然后用初始建树相同方法插入即可。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<vector>
  5 #define lch ch[0]
  6 #define rch ch[1]
  7 #define kch ch[k]
  8 #define xch ch[k^1]
  9 using namespace std;
 10 inline int read()
 11 {    char c=getchar();int x=0,y=1;
 12     while(c<'0'||c>'9'){if(c=='-') y=-1;c=getchar();}
 13     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
 14     return x*y;
 15 }
 16 int inf=0x7fffffff,n,q;
 17 class splay
 18 {    private:
 19         struct node
 20         {    int k,s,h,lazy;
 21             node* pt,*ch[2];
 22             node(const int& key)
 23             {    this->k=key;this->s=1;this->lazy=0;
 24                 this->lch=NULL;this->rch=NULL;
 25             }
 26             inline int sz(){return this?this->s:0;}
 27             inline int key(){return this?this->k:0;}
 28             inline int qh(){return this?this->h:-inf;}
 29             ~node()
 30             {    if(this->lch) delete this->lch;
 31                 if(this->rch) delete this->rch; 
 32             }
 33             inline void mt()
 34             {    if(this) this->s=this->lch->sz()+this->rch->sz()+1;
 35                 if(this) this->h=std::max(this->k,max(this->lch->qh(),this->rch->qh()));
 36             }
 37             inline void dn()
 38             {    if(this&&this->lazy)
 39                 {    if(lch) lch->lazy+=lazy,lch->k+=lazy,lch->h+=lazy;
 40                     if(rch) rch->lazy+=lazy,rch->k+=lazy,rch->h+=lazy;
 41                     lazy=0;
 42                 }
 43             }
 44             inline void Ad(int key){if(this){this->lazy+=key;this->k+=key;this->h+=key;}}
 45             inline int pos(){return this==this->pt->lch;}
 46         }*root;
 47         void rotate(node* rt,int k)
 48         {    node* tmp=rt->xch;
 49             rt->dn();tmp->dn();
 50             tmp->pt=rt->pt;
 51             if(!rt->pt) this->root=tmp;
 52             else if(rt->pt->lch==rt) rt->pt->lch=tmp;
 53             else rt->pt->rch=tmp;
 54             rt->xch=tmp->kch;
 55             if(tmp->kch) tmp->kch->pt=rt;
 56             tmp->kch=rt;rt->pt=tmp;
 57             rt->mt();tmp->mt();
 58         }
 59         void sp(node* rt,node* prt=NULL)
 60         {    while(rt->pt!=prt)
 61             {    int k=rt->pt->lch==rt;
 62                 if(rt->pt->pt==prt) rotate(rt->pt,k);
 63                 else
 64                 {    int d=rt->pt->pt->lch==rt->pt;
 65                     rotate(k==d?rt->pt->pt:rt->pt,k);
 66                     rotate(rt->pt,d);
 67                 }
 68             }
 69         }
 70         node* build(const std::vector<int>& v,int l,int r)
 71         {    if(l>r) return NULL;
 72             int mid=(l+r)>>1;node* tmp=new node(v[mid]);
 73             tmp->lch=build(v,l,mid-1);tmp->rch=build(v,mid+1,r);
 74             if(tmp->lch) tmp->lch->pt=tmp; if(tmp->rch) tmp->rch->pt=tmp;
 75             tmp->mt();
 76             return tmp;
 77         }
 78     public:
 79         ~splay(){delete this->root;}
 80         splay(const std::vector<int>& v){this->root=build(v,0,v.size()-1);}
 81         splay(){this->root=new node(-inf);this->root->rch=new node(-inf);this->root->rch->pt=this->root;}
 82         node* kth(int x)
 83         {    ++x;
 84             node* now=this->root;
 85             while(now!=NULL)
 86             {    now->dn();
 87                 int k=now->lch->sz()+1;
 88                 if(x<k) now=now->lch;
 89                 else if(x==k) return now;
 90                 else x-=k,now=now->rch;
 91             }
 92             return NULL;
 93         }
 94         void add(int x,int y,int z)
 95         {    node* tmp=this->kth(y+1),*tmp2=this->kth(x-1);
 96             this->sp(tmp2);this->sp(tmp,this->root);
 97             this->root->rch->lch->Ad(z);
 98             this->root->rch->mt();this->root->mt();
 99         }
100         void del(int x,int y)
101         {    node* tmp=this->kth(y+1),*tmp2=this->kth(x-1);
102             this->sp(tmp2);this->sp(tmp,this->root);
103             delete this->root->rch->lch;
104             this->root->rch->lch=NULL;
105             this->root->rch->mt();this->root->mt();
106         }
107         int hmax(int x,int y)
108         {    node* tmp=this->kth(y+1),*tmp2=this->kth(x-1);
109             this->sp(tmp2);this->sp(tmp,this->root);
110             return this->root->rch->lch->h;
111         }
112         void insert(int x,splay* data)
113         {    this->sp(this->kth(x));this->sp(this->kth(x+1),this->root);
114             node* tmp=data->root;data->root=NULL;
115             this->root->rch->lch=tmp;tmp->pt=this->root->rch;
116             this->root->rch->mt();this->root->mt();
117         }
118 };
119 int main()
120 {    freopen("equake.in","r",stdin);
121     freopen("equake.out","w",stdout);
122     n=read();q=read();
123     splay* tree=new splay();
124     std::vector<int>v;char ord[10];int x,y,z;
125     for(int i=1;i<=n;i++) v.push_back(read());
126     tree->insert(0,new splay(v));
127     for(int i=1;i<=q;i++)
128     {    scanf("%s",ord);
129         if(ord[0]=='R'){x=read();y=read();z=read();tree->add(x,y,z);}
130         if(ord[0]=='I')
131         {    v.clear();x=read();y=read();
132             while(y--) v.push_back(read());
133             tree->insert(x,new splay(v));
134         }
135         if(ord[0]=='M'){x=read();y=read();tree->del(x,y);}
136         if(ord[0]=='Q'){x=read();y=read();printf("%d\n",tree->hmax(x,y));}
137     }
138     return 0;
139 }
cogs347

 

posted @ 2017-08-05 20:20  ccc000111  阅读(197)  评论(0编辑  收藏  举报