【Splay】 HDU 1754 I Hate It

點擊打開鏈接

區間最值模板 

需要在兩端設置兩個結點( 查詢 [ l, r ] 時需 將 l-1 轉到根結點,r+1轉到l-1的兒子結點 這時 r+1的左兒子就是答案

 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <list>
#include <deque>
#include <set>
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <map>
typedef long long LL;
const int INF = 1<<29;
const LL mod = 1e9+7;
const int MAXN = 200050;
struct SPLAY
{
    int pre[MAXN],key[MAXN],ch[MAXN][2],mx[MAXN],root,tol;
    void init()
    {
        root=0,tol=0;
        ch[root][0]=ch[root][1]=0;
    }
    void NewNode(int &r,int father,int k)
    {
        r= ++tol;
        pre[r]=father;
        key[r]=mx[r]=k;
        ch[r][0]=ch[r][1]=0;
    }
    void pushup(int w)
    {
        mx[w]=max(max(mx[ch[w][0]],mx[ch[w][1]]),key[w]);
    }
    void Rotate(int x,int kind)//0爲左旋,1爲右旋
    {
        int y=pre[x];
        ch[y][!kind]=ch[x][kind];
        pre[ch[x][kind]]=y;
        if(pre[y])
            ch[pre[y]][ch[pre[y]][1]==y]=x;
        pre[x]=pre[y];
        ch[x][kind]=y;
        pre[y]=x;
        pushup(y);
        pushup(x);
    }
    //Splay調整,將r節點調整爲goal的兒子
    void Splay(int r,int goal)
    {
        while(pre[r]!=goal)
        {
            if(pre[pre[r]]==goal)
                Rotate(r,ch[pre[r]][0]==r);
            else
            {
                int y=pre[r];
                int kind=ch[pre[y]][0]==y;
                if(ch[y][kind]==r)
                {
                    Rotate(r,!kind);
                    Rotate(r,kind);
                }
                else
                {
                    Rotate(y,kind);
                    Rotate(r,kind);
                }
            }
        }
        if(goal==0) root=r;
    }
    int query(int l,int r)
    {
        r+=2;
        Splay(l,0);
        Splay(r,l);
        return mx[ch[r][0]];
    }
    void update(int x,int k)
    {
        x++;
        Splay(x,0);
        key[x]=k;
        pushup(x);
    }
    void gao(int n,int m)
    {
        int a,b;
        NewNode(root,0,INF);
        for(int i=2;i<=n+1;i++)
        {
            scanf("%d",&a);
            NewNode(b,i-1,a);
            ch[i-1][1]=i;
        }
        NewNode(a,n+1,-INF);
        ch[n+1][1]=n+2;
//        for(int i=1;i<=n+2;i++)
//            printf("%d :%d %d\n",i,ch[i][0],ch[i][1]);
        for(int i=n+2;i>=1;i--)
            pushup(i);
        char s[4];
        while(m--)
        {
            scanf("%s%d%d",s,&a,&b);
            if(s[0]=='Q')
                printf("%d\n",query(a,b));
            else
                update(a,b);
        }
    }
}s;
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        s.init();
        s.gao(n,m);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章