序列终结者

链接:https://www.luogu.org/problemnew/show/P4146

题解:

平衡树的区间修改操作,注意updata的时候要把左右儿子给down了

另外这题有负数

#include <bits/stdc++.h>
#define maxn 111111
int num,n,m,fa[maxn],data[maxn],maxnumber[maxn],leftson[maxn],
rightson[maxn],lazy[maxn],rev[maxn],count2[maxn],root;
using namespace std;
void down(int x)
{
  if (lazy[x])
  {
      maxnumber[x]+=lazy[x]; data[x]+=lazy[x];
      if (leftson[x]) lazy[leftson[x]]+=lazy[x];
      if (rightson[x]) lazy[rightson[x]]+=lazy[x];
      lazy[x]=0;    
  }    
  if (rev[x])
  {
      swap(rightson[x],leftson[x]);
      if (leftson[x]) rev[leftson[x]]^=1;
      if (rightson[x]) rev[rightson[x]]^=1;
      rev[x]=0;
  }
} 
void updata(int x)
{
    down(leftson[x]);down(rightson[x]); 
    count2[x]=count2[leftson[x]]+count2[rightson[x]]+1;
    maxnumber[x]=max(data[x],max(maxnumber[leftson[x]],maxnumber[rightson[x]]));
}
void rotate(int x,int y)
{
    int father=fa[x];
    down(father); down(x);
    if (y==1)
    {
        rightson[father]=leftson[x]; 
        if (leftson[x]) fa[leftson[x]]=father;
    } else
    {
        leftson[father]=rightson[x];
        if (rightson[x]) fa[rightson[x]]=father;
    }
    fa[x]=fa[father];
    if (fa[father])
    {
        if (leftson[fa[father]]==father)
          leftson[fa[father]]=x;
        else rightson[fa[father]]=x; 
    }
    fa[father]=x;
    if (y==1) leftson[x]=father; else rightson[x]=father;
    updata(father); updata(x);
}
void splay(int x,int goal)
{
    if (x==root) return;
    int father;
    while (fa[x]!=goal)
    {
        father=fa[x];
        if (fa[father]==goal)
        {
            if (x==leftson[father]) rotate(x,2);
            else rotate(x,1);
        } else
        {
            if (father==leftson[fa[father]])
            {
                if (x==leftson[father])
                  rotate(father,2),rotate(x,2);
                else rotate(x,1),rotate(x,2);
            } else
            {
                if (x==rightson[father])
                  rotate(father,1),rotate(x,1);
                else rotate(x,2),rotate(x,1);
            }
        }  
    }
    if (goal==0) root=x;
}
int search(int goal)
{
    int x=root,cnt=1;
    while (x)
    {
        down(x);
        if (cnt+count2[leftson[x]]==goal) return(x);
        if (count2[leftson[x]]+cnt<goal)
        {
            cnt+=count2[leftson[x]]+1; x=rightson[x];
        } else
        {
            x=leftson[x];
        }
    }
}
void insert(int x)
{
   int y=root;
   while (y)
   {
       count2[y]++;
       if (x<data[y])
       {
             if (!leftson[y]) break;
             y=leftson[y];
       } else
       {
             if (!rightson[y]) break;
             y=rightson[y];           
       }
   }    
   data[++num]=0; fa[num]=y; count2[num]=1;
   if (x>data[y]) rightson[y]=num; else leftson[y]=num;
   splay(num,0);
}
void reserve(int x,int y)
{
    int x1=search(x),y1=search(y+2);
    splay(x1,0);
    splay(y1,x1);
    rev[leftson[y1]]^=1;
}
void add(int x,int y,int sum)
{
    int x1=search(x),
    y1=search(y+2);
    splay(x1,0);
    splay(y1,x1);
    lazy[leftson[y1]]+=sum;
}
void query(int x,int y)
{
    int x1=search(x),y1=search(y+2);
    splay(x1,0);
    splay(y1,x1);
    down(leftson[y1]);
    cout<<maxnumber[leftson[y1]]<<endl;
}
int main()
{
    freopen("noip.in","r",stdin);
    freopen("noip.out","w",stdout);
    for (int i=0;i<=maxn-1;i++)
      maxnumber[i]=-2000000000;
    cin>>n>>m;
    for (int i=0;i<=n+1;i++) insert(rand());
    for (int i=1;i<=m;i++)
    {
        //    for (int i=1;i<=n+2;i++) cout<<leftson[i]<<" "<<rightson[i]<<endl;
        int c,d,e,f;
        cin>>c;
        if (c==1)
        {
            cin>>d>>e>>f;
            add(d,e,f);
        }
        if (c==2)
        {
            cin>>d>>e;
            reserve(d,e);
        }
        if (c==3)
        {
            cin>>d>>e;
            query(d,e);
        }
    }
    return 0;
}

 

posted @ 2018-02-02 15:22  尹吴潇  阅读(122)  评论(0编辑  收藏  举报