Description

网上有许多题,就是给定一个序列,要你支持几种操作:A、B、C、D。一看另一道题,又是一个序列,要支持几种操作:D、C、B、A。尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量……这样,我也出一道题,我出这一道的目的是为了让大家以后做这种题目有一个“库”可以依靠,没有什么其他的意思。这道题目 就叫序列终结者吧。

【问题描述】

给定一个长度为N的序列,每个序列的元素是一个整数(废话)。要支持以下三种操作:
1. 将[L,R]这个区间内的所有数加上V
2. 将[L,R]这个区间翻转,比如1 2 3 4变成4 3 2 1
3. 求[L,R]这个区间中的最大值。 最开始所有元素都是0

Input

第一行两个整数NMM为操作个数。
以下M行,每行最多四个整数,依次为KLRVK表示是第几种操作,如果不是第1种操作则K后面只有两个数。

Output

对于每个第3种操作,给出正确的回答。

Sample Input

4 4
1 1 3 2
1 2 4 -1
2 1 3
3 2 4

Sample Output

2

【数据范围】

N<=50000,M<=100000。

HINT

Source

思路

splay。
区间反转和区间加?打标记,标记下传需要注意一下。
求最大值?splay每个节点维护一个最大值,注意更新。

代码

#include <cstdio>

const int maxn=100000;

int n;

struct splay_tree
{
  int fa[maxn+10],son[2][maxn+10],size[maxn+10],val[maxn+10];
  int maxx[maxn+10],lazy[maxn+10],rev[maxn+10],root;

  inline int pushdown(int x)
  {
    if(rev[x])
      {
    int t=son[1][x];
    son[1][x]=son[0][x];
    son[0][x]=t;
    rev[son[0][x]]^=1;
    rev[son[1][x]]^=1;
    rev[x]=0;
      }
    if(son[0][x])
      {
    val[son[0][x]]+=lazy[x];
    lazy[son[0][x]]+=lazy[x];
    maxx[son[0][x]]+=lazy[x];
      }
    if(son[1][x])
      {
    val[son[1][x]]+=lazy[x];
    lazy[son[1][x]]+=lazy[x];
    maxx[son[1][x]]+=lazy[x];
      }
    lazy[x]=0;
    return 0;
  }

  inline int updata(int x)
  {
    size[x]=1;
    maxx[x]=val[x];
    if(son[0][x])
      {
    size[x]+=size[son[0][x]];
    if(maxx[x]<maxx[son[0][x]])
      {
        maxx[x]=maxx[son[0][x]];
      }
      }
    if(son[1][x])
      {
    size[x]+=size[son[1][x]];
    if(maxx[x]<maxx[son[1][x]])
      {
        maxx[x]=maxx[son[1][x]];
      }
      }
    return 0;
  }

  inline int t(int x)
  {
    return son[1][fa[x]]==x;
  }

  inline int rotate(int x)
  {
    int k=t(x),f=fa[x];
    if(fa[f])
      {
    son[t(f)][fa[f]]=x;
      }
    fa[x]=fa[f];
    if(son[!k][x])
      {
    fa[son[!k][x]]=f;
      }
    son[k][f]=son[!k][x];
    fa[f]=x;
    son[!k][x]=f;
    updata(f);
    updata(x);
    return 0;
  }

  inline int splay(int x,int c)
  {
    while(fa[x]!=c)
      {
    int f=fa[x];
    if(fa[f]==c)
      {
        rotate(x);
      }
    else if(t(x)==t(f))
      {
        rotate(f);
        rotate(x);
      }
    else
      {
        rotate(x);
        rotate(x);
      }
      }
    if(!c)
      {
    root=x;
      }
    return 0;
  }

  inline int build(int l,int r)
  {
    int mid=(l+r)>>1;
    val[mid]=0;
    lazy[mid]=0;
    if(l<=mid-1)
      {
    son[0][mid]=build(l,mid-1);
    fa[son[0][mid]]=mid;
      }
    if(mid+1<=r)
      {
    son[1][mid]=build(mid+1,r);
    fa[son[1][mid]]=mid;
      }
    updata(mid);
    return mid;
  }

  inline int getkth(int x)
  {
    int now=root;
    while(now)
      {
    pushdown(now);
    if(size[son[0][now]]+1==x)
      {
        return now;
      }
    else if(size[son[0][now]]+1<x)
      {
        x-=size[son[0][now]]+1;
        now=son[1][now];
      }
    else
      {
        now=son[0][now];
      }
      }
    return 0;
  }

  inline int addnode(int x,int v)
  {
    lazy[x]+=v;
    maxx[x]+=v;
    val[x]+=v;
    return 0;
  }

  inline int add(int l,int r,int v)
  {
    if(l==1)
      {
    if(r==n)
      {
        addnode(root,v);
      }
    else
      {
        int x=getkth(r+1);
        splay(x,0);
        addnode(son[0][x],v);
        updata(x);
      }
      }
    else
      {
    int x=getkth(l-1);
    splay(x,0);
    if(r==n)
      {
        addnode(son[1][x],v);
        updata(x);
      }
    else
      {
        int y=getkth(r+1);
        splay(y,x);
        addnode(son[0][y],v);
        updata(y);
        updata(x);
      }
      }
    return 0;
  }

  inline int reverse(int l,int r)
  {
    if(l==1)
      {
    if(r==n)
      {
        rev[root]^=1;
      }
    else
      {
        int x=getkth(r+1);
        splay(x,0);
        rev[son[0][x]]^=1;
      }
      }
    else
      {
    int x=getkth(l-1);
    splay(x,0);
    if(r==n)
      {
        rev[son[1][x]]^=1;
      }
    else
      {
        int y=getkth(r+1);
        splay(y,x);
        rev[son[0][y]]^=1;
      }
      }
    return 0;
  }

  inline int getmax(int l,int r)
  {
    if(l==1)
      {
    if(r==n)
      {
        return maxx[root];
      }
    else
      {
        int x=getkth(r+1);
        splay(x,0);
        return maxx[son[0][x]];
      }
      }
    else
      {
    int x=getkth(l-1);
    splay(x,0);
    if(r==n)
      {
        return maxx[son[1][x]];
      }
    else
      {
        int y=getkth(r+1);
        splay(y,x);
        return maxx[son[0][y]];
      }
      }
  }
};

splay_tree st;
int m,k,l,r,v;

int main()
{
  scanf("%d%d",&n,&m);
  st.build(1,n);
  st.root=(n+1)>>1;
  while(m--)
    {
      scanf("%d%d%d",&k,&l,&r);
      if(k==1)
    {
      scanf("%d",&v);
      st.add(l,r,v);
    }
      else if(k==2)
    {
      st.reverse(l,r);
    }
      else
    {
      printf("%d\n",st.getmax(l,r));
    }
    }
  return 0;
}