• 替罪羊树&&非旋treap


    题解:

    替罪羊树的模板和splay差距还是比较大的。。

    按照我的splay的写法 真是都是问题。。

    替罪羊树就是暴力的搞

    当某颗子树大小大于这棵树的alpha时 就退出

    另外删除的时候打懒标记删除

    当有用个数少于alpha*n的时候,就重构

    注意点:

    1.找rank的时候要找比它小的个数,不能像splay那样取min

    2.删除的时候要删排名为这个的,不能删这个数

    以上两点的原因是

    不能保证相同元素一定在左子树内,因为重构可能造成在右子树

    另外找pre和scc也就不能和splay一样了

    rank(x) 找的是编号最小的那个

    rank(x)-1就是前驱

    rank(x+1) 就是后继

    替罪羊树不支持区间操作

    应该写它的用处就是用来搞毒瘤树套树的。。

    #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 mid ((h+t)>>1)
    const double alpha=0.75;
    const int INF=2e9+10; 
    const int N=4e6+10;
    int s[N],n,m,top,rt,t1;
    struct phs{
      int ls[N],rs[N],siz[N],travel[N],cnt[N],v[N];
      bool f[N];
      void dfs(int x)
      {
        if (!x) return;
        dfs(ls[x]);
        if (f[x]) travel[++t1]=x;
        else s[++top]=x; 
        dfs(rs[x]);
      }
      void build(int &x,int h,int t)
      {
        x=travel[mid];
        if (h==t)
        {
          siz[x]=cnt[x]=1;
          ls[x]=rs[x]=0;
          return;
        }
        if (h<mid) build(ls[x],h,mid-1); else ls[x]=0;
        build(rs[x],mid+1,t);
        siz[x]=siz[ls[x]]+siz[rs[x]]+1;
        cnt[x]=cnt[ls[x]]+cnt[rs[x]]+1;
      }
      void rebuild(int &x)
      {
        t1=0; dfs(x);
        if (t1) build(x,1,t1);
        else x=0;
      }
      void insert(int &x,int k)
      {
        if (!x)
        {
          x=s[top--]; v[x]=k;
          siz[x]=cnt[x]=f[x]=1;
          ls[x]=rs[x]=0;
          return;
        }
        siz[x]++; cnt[x]++;
        if (k<=v[x]) insert(ls[x],k);
        else insert(rs[x],k);
           if ((double)max(siz[ls[x]],siz[rs[x]])>(double)siz[x]*alpha)
        {
          rebuild(x);
        } 
      }
      void del(int x,int k)
      {
        siz[x]--;
        if (f[x]&&k==v[x])
        {
          f[x]=0; return;
        }
        if (k<=v[x]) del(ls[x],k);
        else del(rs[x],k);
      }
      void del(int k)
      {
        int now=rt;
        while (now)
        {
          siz[now]--;
          if (f[now]&&k==siz[ls[now]]+1)
          {
            f[now]=0; 
            return;
          }
          if (k<=siz[ls[now]]) now=ls[now];
          else k-=siz[ls[now]]+f[now],now=rs[now];
        }
      }
      void delete2(int x)
      {
        del(x);
       if ((double)siz[rt]<(double) alpha*cnt[rt]) rebuild(rt);
      }
      int rank(int x)
      {
        int now=rt,ans=1;
        while (now)
        {
          if (v[now]>=x) now=ls[now];
          else ans+=siz[ls[now]]+f[now],now=rs[now];
        }
        return(ans);
      }
      int get_kth(int x)
      {
        int now=rt;
        while (now)
        {
          if (f[now]&&x==siz[ls[now]]+1) return(v[now]);
          if (siz[ls[now]]>=x) now=ls[now];
          else x-=siz[ls[now]]+f[now],now=rs[now];
        }
      }
    }S;
    int main()
    {
      freopen("1.in","r",stdin);
      freopen("1.out","w",stdout);
      ios::sync_with_stdio(false); 
      cin>>n;
      dep(i,4000000,1) s[++top]=i;
      rep(i,1,n)
      {
       // cout<<i<<endl; 
        int kk,x;
        cin>>kk>>x;
        if (kk==1)
        {
          S.insert(rt,x);
        }
        if (kk==2)
        {
          S.delete2(S.rank(x));
        }
        if (kk==3)
        {
          cout<<S.rank(x)<<endl; 
        }
        if (kk==4)
        {
          cout<<S.get_kth(x)<<endl;
        }
        if (kk==5)
        {
          cout<<S.get_kth(S.rank(x)-1)<<endl;
        }
        if (kk==6)
        {
          cout<<S.get_kth(S.rank(x+1))<<endl;
        }
      }
      return 0; 
    }
      

    https://zhuanlan.zhihu.com/p/21263304

  • 相关阅读:
    2020第29周日
    pytest文档44-allure.dynamic动态生成用例标题
    python笔记46-史上最强大最好用的python日志模块nb_log
    pytest文档43-元数据使用(pytest-metadata)
    pytest文档42-fixture参数化params
    ASP.NET Core WebApi+EF Core入门到实战演练
    SqlParameter中的new SqlParameter("e",0)的陷阱坑,你知道?
    EF Linq中的左连接Left Join查询
    .NET Core EFCore零基础快速入门简单使用
    git报错,远程克隆和更新不下来解决方法
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/9704396.html
Copyright © 2020-2023  润新知