On splay trees (Splay)

// This article is a temporary small mind, there is something wrong, please point out bigwigs -
the real heavyweights in this http://blog.csdn.net/clove_unique/article/details/50630280

Splay trees (Splay Tree), also known as split tree is a binary sort tree, it can complete the insertion in O (log n), find and delete operations. It consists of Daniel Adams litas Daniel Sleator and Robert Enzhuo Tasso Young Robert Endre Tarjan invention in 1985.
In general operation based on the extended tree are the stretching operation: Suppose you want to find a binary tree to perform a series of lookup operations, in order to make smaller the whole seek time, those entries should be high frequencies often in the inspected near the roots s position. I think of a simple way to design, reconstructing the tree after each search, the entry being sought to move away from the roots closer. Splay trees came into being. Stretch tree is a self-adjusting form of binary search tree, it along a path between a node from the root, through a series of rotating to move to the root node.
It has the advantage of redundant information need not be recorded for the balance of the tree.

(This paragraph from Baidu)

The basic operation of Splay

  • get operation
    is mainly used to find the node x belonging to his father's son nodes left or right son
int get(int x)
{
    return son[fa[x]][1]==x;
}
  • update operating
    mainly update size value
    (sometimes also update the other)
void update(int x)
{  
     if (x)
     {  
          size[x]=1; 
          if (son[x][0]) size[x]+=size[son[x][0]];  
          if (son[x][1]) size[x]+=size[son[x][1]]; 
     }  
}  
  • rotate (rotating) operation
    which is Splay most common and most important operation of the
    specific operation is to find the relationship between x and father (he left his son or right son), then spin up, a direct replacement for his father's position, and then a series of "son adopt" (see the specific codes)
int rotate(int x)
{
    int k=get(x),y=fa[x];
    if(fa[y])son[fa[y]][get(y)]=x;
    if(son[x][!k])fa[son[x][!k]]=y;//x结点反方向的儿子
    fa[x]=fa[y],fa[y]=x,son[y][k]=son[x][!k],son[x][!k]=y;//认领儿子
    update(y),update(x);
}

Then an example, I believe that [did] with the maximum tree line, this question is very good, but there are a range of modifications, into a maximum of [2], now implemented Splay:
the subject does not remember it ~

Description

 For M (1 <= M <= 100000) on the number A1 at N (1 <= N <= 100000) ... An operation composed of a sequence of views, there are two operations:
  (. 1) the LRC. 1: represents the A [L ] to a [R] C increase (the absolute value of C is not more than 10000);
  (2) the LR 2: Inquiry a [L] to a maximum value between a [R].

Think about ~

OK, so we only need to speak above all operation inside labeled join a fight just fine.
And this almost tree line, so after the flag lazy, downstream ~

#include<cstdio>
#include<iostream>
#define LL long long
using namespace std;
int son[100001][2];//Son
LL fmax[100001];//Ans
int fa[100001];//Father
LL add[100001];//Lazy
LL a[100001];//Data
int d[100001];//Queue
int n,m,kind,l,r,c;
int update(int x){fmax[x]=max(a[x],max(fmax[son[x][0]],fmax[son[x][1]]));}
int lazy(int x,int c){fmax[x]+=c,a[x]+=c,add[x]+=c;}
int get(int x){return son[fa[x]][1]==x;}
int clear(int x)
{
    if(son[x][0])lazy(son[x][0],add[x]);
    if(son[x][1])lazy(son[x][1],add[x]);
    add[x]=0;
}
int remove(int x,int y)
{
    d[0]=0;
    for (x=x;x-y;x=fa[x]) d[++d[0]]=x;
    while (d[0]) clear(d[d[0]--]);  
}
int rotate(int x)
{
    int k=get(x),y=fa[x];
    if(fa[y])son[fa[y]][get(y)]=x;
    if(son[x][!k])fa[son[x][!k]]=y;
    fa[x]=fa[y],fa[y]=x,son[y][k]=son[x][!k],son[x][!k]=y;
    update(y),update(x);
}
int Splay(int x,int y)
{
    remove(x,y);
    while(fa[x]-y)
    {
        if(fa[fa[x]]-y)
            if(get(x)==get(fa[x])) rotate(fa[x]);
            else rotate(x);
        rotate(x);
    }
}
int main()
{
    freopen("Max2.in","r",stdin);
    scanf("%d",&n);
    int i;fmax[0]=-1e9;
    for (i=1;i<=n;++i)
        scanf("%lld",&a[i+1]),fa[i]=i+1,son[i+1][0]=i,update(i+1);
    fa[n+1]=n+2,son[n+2][0]=n+1,update(n+2);
    scanf("%d",&m);
    for (i=1;i<=m;++i)
    {
        scanf("%d%d%d",&kind,&l,&r);++l,++r;
        Splay(l-1,0),Splay(r+1,l-1);
        if(kind-2){scanf("%d",&c),lazy(son[r+1][0],c);}
        else printf("%lld\n",fmax[son[r+1][0]]);
    }
}

JZOJ [9.12] square and analog NOIP2015

#include<cstdio>
#include<iostream>
#define maxn 200010
#define mo 7459
#define ll long long
using namespace std;
struct Moon{
    ll tag,key,size;
    ll sum,sum2,fa;
}t[4*maxn];
ll son[maxn][2],d[maxn];
ll n,a[maxn],m,x,y,z,root,sz;
ll get(ll x)
{
    return son[t[x].fa][1]==x;
}
void update(ll x)
{
    t[x].size=t[son[x][0]].size+t[son[x][1]].size+1;
    (t[x].sum=t[son[x][0]].sum+t[son[x][1]].sum+t[x].key)%=mo;
    (t[x].sum2=t[son[x][0]].sum2+t[son[x][1]].sum2+t[x].key*t[x].key)%=mo;
}
ll findx(ll num)
{
    ll v=root;
    while(x)
    {
        if(son[v][0]&&t[son[v][0]].size>=num) v=son[v][0];
        else 
        {
            ll cnt=t[son[v][0]].size+1;
            if(cnt==num) return v;
            num-=cnt;
            v=son[v][1];
        }
    }
    return v;
}
void rotate(ll x)
{
    ll k=get(x),y=t[x].fa;
    if(t[y].fa) son[t[y].fa][get(y)]=x;
    if(son[x][!k]) t[son[x][!k]].fa=y;
    t[x].fa=t[y].fa,son[y][k]=son[x][!k];
    son[x][!k]=y,t[y].fa=x;
    update(y),update(x);
}
ll Sum(ll x,ll b)
{
    ll ans=((t[x].sum2+2*b*t[x].sum)%mo+t[x].size*b*b%mo)%mo;
    return ans;
}
void clear(ll x)
{
    if(t[x].tag)
    {
        for (ll i=0;i<=1;++i)
        {
            if(!son[x][i]) continue;
            (t[son[x][i]].key+=t[x].tag)%=mo;
            (t[son[x][i]].tag+=t[x].tag)%=mo;
            t[son[x][i]].sum2=Sum(son[x][i],t[x].tag%mo);
            (t[son[x][i]].sum+=t[son[x][i]].size*t[x].tag)%=mo;
        }
        t[x].tag=0;
    }
}
void remove(ll x,ll y)
{
    d[0]=0;
    for (;x!=y;x=t[x].fa) d[++d[0]]=x;
    for (ll i=d[0];i>=1;--i) clear(d[i]);
} 
void splay(ll x,ll y)
{
    remove(x,y);
    while(t[x].fa!=y)
    {
        if(t[t[x].fa].fa!=y) 
            if(get(x)==get(t[x].fa)) rotate(t[x].fa);
            else rotate(x);
        rotate(x);
    }
    if(y==0) root=x;
}
void add(ll x,ll c)
{
    (t[x].key+=c)%=mo;
    (t[x].tag+=c)%=mo;
    t[x].sum2=Sum(x,c);
    (t[x].sum+=t[x].size*c%mo)%=mo;
}
int main()
{
    scanf("%lld",&n);
    ll i,j,xx,yy;char k;
    for (i=1;i<=n;++i) scanf("%lld",&a[i+1]);
    for (i=2;i<=n+2;++i) son[i][0]=i-1,t[i-1].fa=i,t[i-1].key=a[i-1],update(i-1);
    update(n+2);
    scanf("%lld\n",&m);root=sz=n+2;
    for (i=1;i<=m;++i)
    {
        scanf("%c",&k);
        if(k=='Q')
        {
            scanf("uery%lld%lld\n",&x,&y);++x,++y;
            yy=findx(y+1),xx=findx(x-1);
            splay(xx,0);
            splay(yy,xx);
            printf("%lld\n",(t[son[yy][0]].sum2+mo)%mo);
        }
        if(k=='I')
        {
            scanf("nsert%lld%lld\n",&x,&y);++x; 
            xx=findx(x-1),yy=findx(x);
            splay(xx,0),splay(yy,xx);
            son[yy][0]=++sz,t[sz].fa=yy;
            t[sz].key=t[sz].sum=y,t[sz].sum2=y*y%mo,t[sz].size=1;
            update(yy),update(xx);
        }
        if(k=='A')
        {
            scanf("dd%lld%lld%lld\n",&x,&y,&z);++x,++y;
            yy=findx(y+1),xx=findx(x-1);
            splay(xx,0),splay(yy,xx);
            add(son[yy][0],z);
        }
    }
}

Guess you like

Origin www.cnblogs.com/Chandery/p/11332812.html