• 序列终结者


    链接: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;
    }
  • 相关阅读:
    firefox, chrome常见插件
    数据库左连接left join、右连接right join、内连接inner join on 及 where条件查询的区别
    Springmvc + mybatis + spring 配置,spring事物
    Android如何连接MySQL数据库
    Android MP3录音实现
    Android RecyclerView的基本使用
    Java输入流之BufferReader和Scanner的用法!
    Android 网络通信框架Volley简介
    your project contains error(s),please fix them before running your application.错误总结
    新建android项目报错,代码中找不到错误
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8405373.html
Copyright © 2020-2023  润新知