首页 > 其他分享 >SPOJ4487(Splay树)

SPOJ4487(Splay树)

时间:2023-05-31 17:31:47浏览次数:41  
标签:pre Node ch int Splay SPOJ4487 null root


题目:http://www.spoj.com/problems/GSS6/

 

题意:给一个长度为n的数组,然后给出Q个4种操作,分别是:删除,插入,替换,查找指定区间连续最大和。

#include <iostream>
#include <string.h>
#include <stdio.h>

using namespace std;
const int N = 200005;
const int INF = 1<<28;

int a[N];

struct Node
{
    int val,sz;
    int sum,ml,mr,mc;
    Node *pre,*ch[2];
};

class Splay
{
    public:
    Node *null,*root,*S[N],data[N];
    int cnt,top;

    Node *getNewNode(int x)
    {
        Node *p;
        if(top) p = S[top--];
        else    p = &data[cnt++];
        p->val = p->sum = p->ml = p->mr = p->mc = x;
        p->sz = 1;
        p->ch[0] = p->ch[1] = p->pre = null;
        return p;
    }

    void init()
    {
        cnt = top = 0;
        null = getNewNode(-INF);
        null->sum = null->sz = 0;
        root = getNewNode(-INF);
        root->sum = 0;
        root->ch[1] = getNewNode(INF);
        root->ch[1]->sum = 0;
        root->ch[1]->pre = root;
        update(root);
    }


    void update(Node *p)
    {
        p->sz = p->ch[0]->sz + p->ch[1]->sz + 1;
        p->sum = p->ch[0]->sum + p->ch[1]->sum + p->val;
        p->ml = max(p->ch[0]->ml,p->ch[0]->sum + p->val + max(p->ch[1]->ml,0));
        p->mr = max(p->ch[1]->mr,p->ch[1]->sum + p->val + max(p->ch[0]->mr,0));
        p->mc = max(p->ch[0]->mc,p->ch[1]->mc);
        p->mc = max(p->mc,max(p->ch[0]->mr + p->ch[1]->ml,0) + p->val);
        p->mc = max(p->mc,max(p->ch[0]->mr,p->ch[1]->ml) + p->val);
    }

    void rotate(Node *x,int c)
    {
        Node *y = x->pre;
        y->ch[!c] = x->ch[c];
        if(x->ch[c] != null)
            x->ch[c]->pre = y;
        x->pre = y->pre;
        if(y->pre != null)
        {
            if(y->pre->ch[0] == y)
                y->pre->ch[0] = x;
            else
                y->pre->ch[1] = x;
        }
        x->ch[c] = y;
        y->pre = x;
        if(y == root)
            root = x;
        update(y);
    }

    void splay(Node *x,Node *f)
    {
        while(x->pre != f)
        {
            if(x->pre->pre == f)
                rotate(x,x->pre->ch[0] == x);
            else
            {
                Node *y = x->pre;
                Node *z = y->pre;
                if(z->ch[0] == y)
                {
                    if(y->ch[0] == x)
                        rotate(y,1),rotate(x,1);
                    else
                        rotate(x,0),rotate(x,1);
                }
                else
                {
                    if(y->ch[1] == x)
                        rotate(y,0),rotate(x,0);
                    else
                        rotate(x,1),rotate(x,0);
                }
            }
        }
        update(x);
    }

    void select(int k,Node *f)
    {
        int tmp;
        Node *t = root;
        while(true)
        {
            tmp = t->ch[0]->sz;
            if(tmp + 1 == k) break;
            if(k <= tmp) t = t->ch[0];
            else
            {
                k -= tmp + 1;
                t = t->ch[1];
            }
        }
        splay(t,f);
    }

    void insert(int pos,int val)
    {
        Node *tmproot = getNewNode(val);
        select(pos-1,null);
        select(pos,root);
        root->ch[1]->ch[0] = tmproot;
        tmproot->pre = root->ch[1];
        splay(root->ch[1],null);
    }

    void del(int k)
    {
        select(k,null);
        Node *old_root = root;
        root = root->ch[1];
        root->pre = null;
        select(1,null);
        root->ch[0] = old_root->ch[0];
        root->ch[0]->pre = root;
        update(root);
        S[++top] = old_root;
    }

    void replace(int x,int y)
    {
        select(x,null);
        root->val = y;
        update(root);
    }

    Node *build(int l,int r)
    {
        if(l>r) return null;
        int m = (l + r) >> 1;
        Node *p = getNewNode(a[m]);
        p->ch[0] = build(l,m-1);
        if(p->ch[0] != null)
            p->ch[0]->pre = p;
        p->ch[1] = build(m+1,r);
        if(p->ch[1] != null)
            p->ch[1]->pre = p;
        update(p);
        return p;
    }
};

Splay sp;

int main()
{
    char c;
    int n,m,x,y;
    sp.init();
    scanf("%d",&n);
    for(int i = 1; i <= n; i++)
        scanf("%d",&a[i]);
    Node *troot = sp.build(1,n);
    sp.root->ch[1]->ch[0] = troot;
    troot->pre = sp.root->ch[1];
    sp.update(sp.root->ch[1]);
    sp.update(sp.root);
    sp.splay(sp.root->ch[1],sp.null);
    scanf("%d",&m);
    for(int i = 1; i <= m ; i++)
    {
        scanf(" %c",&c);
        if(c == 'I')
        {
            scanf("%d %d",&x,&y);
            sp.insert(++x,y);
        }
        else if(c == 'D')
        {
            scanf("%d",&x);
            sp.del(++x);
        }
        else if(c == 'R')
        {
            scanf("%d %d",&x,&y);
            sp.replace(++x,y);
        }
        else if(c == 'Q')
        {
            scanf("%d %d",&x,&y);
            sp.select(++x - 1,sp.null);
            sp.select(++y + 1,sp.root);
            printf("%d\n",sp.root->ch[1]->ch[0]->mc);
        }
    }
    return 0;
}

 

标签:pre,Node,ch,int,Splay,SPOJ4487,null,root
From: https://blog.51cto.com/u_16146153/6388689

相关文章

  • BZOJ1503(Splay)
    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1503 #include<iostream>#include<string.h>#include<stdio.h>usingnamespacestd;structNode{intval,size,cnt,lazy;Node*pre,*ch[2];Node(){size=lazy......
  • display:flex
    display:flex是CSS3中的一种布局方式,它可以让元素以弹性盒子模型的方式进行排列,从而实现灵活的布局效果。该属性可以应用于任意元素,使其成为一个弹性容器,内部的子元素则根据弹性容器的排列规则进行布局。使用display:flex属性时,弹性容器的子元素会默认成为弹性项目,它们可以通过设......
  • 获取并改变display的值
    1.获取display的值//jquery.css("display")//js.style.display; 2.更改display的值//jquery方式.css("display","none");//js方式.style.display="none"; 转自https://blog.csdn.net/qq_41121204/article/details/92995933......
  • 【Shell】Display the ddl for all users in Oracle DB with bash script
     脚本说明:1、普遍用于使用expdp/impdp数据泵进行的数据(全库或者特定schemas)迁移2、适用于无PDB的Oracle环境3、适用于RAC,SI,ADG以及多实例的环境 使用方法:创建脚本为 display_all_users_ddl.sh然后将正文内容贴入并保存,然后执行bash display_all_users_ddl.sh......
  • ZCL_QALV_DISPLAY
    IntroductionHistoryPublicMethodGRID_TABNAMEGRID_ALVIDGRID_CUSTGET_VARIANTGET_FCAT_TABNAMEGET_FCAT_ALVIDCONTAINER_FACTORYEVENTIntroductionClass:ZCL_QALV_DISPLAYALV簡化用法(純Display,不可進editmode)HistoryVersionDateNameDescrip......
  • How to connect to multiple SSD1306 OLED Displays using Raspberry Pi GPIO I2C PIN
    HowtoconnecttomultipleSSD1306OLEDDisplaysusingRaspberryPiGPIOI2CPINAllInOne如何使用RaspberryPi的GPIOI2CPIN连接多个SSD1306OLED显示器demos(......
  • Raspberry Pi & 0.96 inch OLED display All In One
    RaspberryPi&0.96inchOLEDdisplayAllInOneI2CGPIOPythondemos(......
  • 【模板】 Splay
    splay#include<bits/stdc++.h>usingnamespacestd;constintN=5e6+10;intval[N],cnt[N],fa[N],ch[N][2],siz[N];inttot,root;voidmaintain(intx){ siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+cnt[x];}boolget(intx){ returnx==ch......
  • OrchardCore 中的 插件开发/ Shape / DisplayDriver / 视图扩展 / Razor代码注入
    请注意该文章仅限于OrchardCore项目中的DisplayDriver扩展机制,ASP.NETCOREMVC自身并没有对应功能,如果需要可以将相关的OrchardCore模块添加到项目中也可以实现响应功能背景最近一个功能需求,需要使用其它用户模拟身份,所以计划在用户列表页面扩展按钮组功能那么开始看代......
  • 使用nacos配置,启动服务时一直报 Error starting ApplicationContext. To display the
    报错日志如下:ErrorstartingApplicationContext.Todisplaytheconditionsreportre-runyourapplicationwith'debug'enabled.-2023-05-0509:46:02.328[TID:N/A]ERROR8236---[main]o.s.b.d.LoggingFailureAnalysisReporter:***********......