• Chino的数列


    题解:

    一道练代码能力的题目。。

    首先很显然他是一道平衡树裸题

    第5个操作是势能分析维护最大值最小值就可以了

    另外设置虚点和noip2017队列那题一样(不过我只写过线段树)

    具体细节:

    1.内存池,要直接判断(!x) 因为可能进去就是0

    2.输出的时候有重复的要都输出

    3.search的时候要down

    4.为了简单我写的down是更新自己的,而这个标记会对updata产生影响,所以updata的时候要down两个儿子

    5.splay虚点变变三个点要判断点数,分三种情况 1个点,2个点,>2个点

    这个洛谷评测是什么鬼。。数据测出来是对的显示wa

    另外本题也可以用分块做。。以后写下试试

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define rint register int
    #define IL inline
    #define rep(i,h,t) for (rint i=h;i<=t;i++)
    #define dep(i,t,h) for (rint i=t;i>=h;i--) 
    #define me(x) memset(x,0,sizeof(x))
    #define ll long long
    const int INF=1e9;
    const int N=4e6;
    queue<int> q;
    int s[N],count2[N],count3[N],data[N],maxa[N],mina[N],rs[N],ls[N],lazy[N],fa[N],root; 
    #define max(a,b) (a)>(b)?(a):(b)
    #define min(a,b) (a)<(b)?(a):(b)
    int cnt,minxx=INF;
    struct phs{
      IL void down(rint x)
      {
        if (lazy[x]==INF) return;
        maxa[x]=mina[x]=data[x]=lazy[x];
        if (ls[x]) lazy[ls[x]]=lazy[x];
        if (rs[x]) lazy[rs[x]]=lazy[x];
        lazy[x]=INF;
      }
      IL void updata(rint x)
      {
        rint l=ls[x],r=rs[x],tmp=data[x];
        down(l); down(r);
        count2[x]=count2[l]+count2[r]+count3[x];
        maxa[x]=max(tmp,max(maxa[l],maxa[r]));
        mina[x]=min(tmp,min(mina[l],mina[r]));
      }
      IL void rotate(int x,int y)
      {
        int fa1=fa[x];
        if (y==1)
        {
          if (ls[x]) fa[ls[x]]=fa1;
          rs[fa1]=ls[x];
        } else
        {
          if (rs[x]) fa[rs[x]]=fa1;
          ls[fa1]=rs[x];
        }
        fa[x]=fa[fa1];
        if(fa[fa1])
        {
          if (ls[fa[fa1]]==fa1) ls[fa[fa1]]=x;
          else rs[fa[fa1]]=x;
        }
        fa[fa1]=x;
        if (y==1) ls[x]=fa1; else rs[x]=fa1;
        updata(fa1); 
        updata(x);
      }
      void dfs(int x)
      {
        if (fa[x]) dfs(fa[x]);
        down(x);
      }
      IL void splay(int x,int goal)
      {
        dfs(x);
        int fa1=fa[x];
        while (fa1!=goal)
        {
          if (fa[fa1]==goal)
          {
            if (x==ls[fa1]) rotate(x,2); else rotate(x,1);
          } else
          if (fa1==ls[fa[fa1]])
            if (x==ls[fa1])
              rotate(fa1,2),rotate(x,2);
            else rotate(x,1),rotate(x,2);
          else 
            if (x==rs[fa1])
              rotate(fa1,1),rotate(x,1);
            else rotate(x,2),rotate(x,1);
          fa1=fa[x];
        }
        if (goal==0) root=x;
      }
      IL int search(rint k)
      {
        rint x=root;
        while (x)
        {
          down(x); 
          if (s[x])
          {
            rint l=ls[x],r=rs[x];
            rint tmp=count3[x];
            count3[x]=1;
            rint now=ls[x]=q.front(); q.pop();
            fa[now]=x;
            if ((count3[ls[x]]=tmp/2)!=1) s[now]=1;
            ls[now]=l; fa[l]=now; data[now]=data[x]; updata(now); 
            if (tmp>2)
            {
              now=rs[x]=q.front(); q.pop(); data[rs[x]]=data[x];
              fa[now]=x;
              if ((count3[now]=tmp-(tmp/2)-1)!=1) s[now]=1;
              rs[now]=r; fa[r]=now; updata(now);
            }
            down(x);
            s[x]=0;
          }
          if (count2[ls[x]]+1==k) return(x);
          if (count2[ls[x]]+1<k) k-=count2[ls[x]]+1,x=rs[x];
          else x=ls[x];
        }
      }
      void dfs2(int x)
      {
        if (!x) return;
        cnt++;
        q.push(x);
        dfs2(ls[x]);
        dfs2(rs[x]);
        ls[x]=rs[x]=count2[x]=s[x]=data[x]=fa[x]=maxa[x]=mina[x]=0;
        count3[x]=1;
        lazy[x]=INF; 
      }
      IL void split(int x,int y)
      {
        splay(x,0); 
        splay(y,x);
      }
      IL void cl(int x)
      {
        down(x);
        int k1=sqrt(maxa[x]); int k2=sqrt(mina[x]);
        if (k1==k2)
        {
          lazy[x]=k1; down(x);
          return;
        }
        data[x]=sqrt(data[x]);
        if (ls[x]) cl(ls[x]);
        if (rs[x]) cl(rs[x]);
        updata(x);
      }
      IL void ycl()
      {
        root=1; rs[1]=2; fa[2]=1; count2[1]=2; count2[2]=1;
      }
      IL void ou(int x)
      {
        down(x);
        if (ls[x]) ou(ls[x]);
        if (x!=1&&x!=2)
          rep(i,1,count3[x]) 
            printf("%d ",data[x]); 
        if (rs[x]) ou(rs[x]);
      }
    }S;
    int main()
    {
      freopen("1.in","r",stdin);
      freopen("1.out","w",stdout);
      ios::sync_with_stdio(false);
      int m;
      cin>>m;
      maxa[0]=-INF; mina[0]=INF;
      int len=0;
      rep(i,3,N-1) q.push(i);
      rep(i,0,N-1) lazy[i]=INF,count3[i]=1;
      S.ycl();
      rep(i,1,m)
      {
        minxx=min(minxx,q.size());
        int x,y,z,k;
        cin>>k;
        if (k==1)
        {
          cin>>x>>y;
          rint now=S.search(len+1);
          S.splay(2,0); 
          S.splay(now,2);
          rint now2=rs[now]=q.front(); q.pop();
          count3[now2]=x; data[now2]=y; fa[now2]=now;  
          if (x!=1) s[now2]=1;
          S.splay(now2,0);
          len+=x;
        }
        if (k==2)
        {
          int x;
          cin>>x;
          len-=x;
          x=S.search(x+2);
          S.split(1,x);
    //      S.dfs2(ls[x]);
          ls[x]=0;
          S.splay(x,0);
        }
        if (k==3)
        {
          int kk;
          cin>>x>>y>>z>>kk;
          rint t=y-x+1;
          rint ans=1;
          while(z)
          {
            if (z&1) ans=(1ll*ans*t)%kk;
            t=(1ll*t*t)%kk;
            z>>=1;
          }
          int l=S.search(x);
          int r=S.search(y+2); 
          S.split(l,r);
          lazy[ls[r]]=ans;
          S.splay(ls[r],0);
        }
        if (k==4)
        {
          int x,y;
          cin>>x>>y;
          //cout<<x<<" "<<y<<endl;
          len-=y-x; 
          x=S.search(x),y=S.search(y+2);
          S.split(x,y);
          S.down(ls[y]);
          int now=ls[y];
          int mm=maxa[now];
      //    S.dfs2(ls[now]); S.dfs2(rs[now]);
          ls[now]=rs[now]=0; lazy[now]=INF; count3[now]=1; s[now]=0;
          data[now]=mm; S.splay(now,0);
          printf("%d
    ",mm);
        }
        if (k==5)
        {
          cin>>x>>y;
          x=S.search(x),y=S.search(y+2);
          S.split(x,y);
          int now=ls[y];
          S.cl(now); 
        }
      }
      S.ou(root);
    //  printf("
    %d
    %d",cnt,minxx);
      return 0; 
    }
  • 相关阅读:
    懂一点Python系列——快速入门
    DatagridView 控件列顺序与设置的不一样
    WinForm Column cannot be added because its CellType property is null.
    Rabbitmq消息服务器通讯异常: name must not be blank
    Redis 数据库
    redis 安装与使用
    windows 服务的安装与卸载之bat脚本命令
    以超级管理员方式运行bat文件
    CMD 下切换目录
    C#导出Excel后关闭进程EXCEL.EXE
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9497398.html
Copyright © 2020-2023  润新知