zoukankan      html  css  js  c++  java
  • 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
    ",tree->hmax(x,y));}
    137     }
    138     return 0;
    139 }
    cogs347
    只要是活着的东西,就算是神我也杀给你看。
  • 相关阅读:
    任务管理器程序——让任务更好的完成
    任务管理器——让你的任务更好的完成 助力中考
    Re:萌娘百科上的黑幕实现
    404 页面不存在
    JavaScript中,数组和对象的遍历方法总结
    JavaScript Math方法的基本使用
    html css二级导航栏
    css常用元素通用样式表
    web前端sprite,精灵图,雪碧图
    个人总结
  • 原文地址:https://www.cnblogs.com/Loser-of-Life/p/7291274.html
Copyright © 2011-2022 走看看