萌新求助平衡树
查看原帖
萌新求助平衡树
367190
LemonLime楼主2020/11/20 22:19

Thanks for debuging.

#include <iostream>
#include <cstdio>
#include <climits>
#include <algorithm>
#include <cctype>
#include <cstring>
using namespace std;

namespace IO
{
    inline char getc(void)
    {
        static const int IN_LEN=1<<21|1;static char buf[IN_LEN],*s,*t;
        return (s==t)&&(t=(s=buf)+fread(buf,1,IN_LEN,stdin)),s==t?-1:*s++;
    }
    template<typename tp>
    void read(tp& a)
    {
        register tp num=0;register int f=1;register char ch=getc();
        while(!isdigit(ch) && ch!='-') ch=getc();
        if(ch=='-') f=-1,ch=getc();
        do
            num=num*10+int(ch-'0'),ch=getc();
        while(isdigit(ch));
        a=num*f;
    }
    template<typename tp,typename...Args>
    void read(tp& a,Args&...args){	read(a);read(args...);	}
}using namespace IO;

typedef unsigned int uint;
typedef const unsigned int cuint;
typedef const int cint;

inline uint randnum(uint& seed,cuint& last,cuint& m)
{
    seed=seed*17+last;
    return seed%m+1;
}

cint MAXN=1e5+5;
uint n,m,seed,tot;
uint last=7;
struct item
{
    typedef const item citem;
    uint cnt,rec;
    item(){}
    item(cuint cnt,cuint rec):cnt(cnt),rec(rec){}
    bool operator<=(citem& a)const  {return cnt!=a.cnt?cnt<a.cnt:rec>a.rec;}
    bool operator==(citem& a)const  {return cnt==a.cnt && rec==a.rec;}
    item operator+=(citem& a)       {return *this=item(cnt+a.cnt,rec+a.rec);}
    friend item max(citem& a,citem& b)    {return a<=b?b:a;}
    friend item min(citem& a,citem& b)    {return a<=b?a:b;}
}a[MAXN];
typedef const item citem;
struct node
{
    node *lson,*rson;
    item val;int w;
    node(){}
    node(node *lson,node *rson,citem val,cint w):lson(lson),rson(rson),val(val),w(w){}
}*null,*root,tr[MAXN<<1],*pool[MAXN<<1];
class WBLT
{
private:
    static const int ratio=4;
    inline node* newnode(node *lson,node *rson,citem val,cint w)
    {
        return &(*pool[++tot]=node(lson,rson,val,w));
    }
    inline node* merge(node *u,node *v)
    {
        return newnode(u,v,v->val,u->w+v->w);
    }
    inline void pushup(node *cur)
    {
        if(cur->lson==null || cur->rson==null)  return;
        cur->w=cur->lson->w+cur->rson->w;
        cur->val=cur->rson->val;
    }
    inline void maintain(node *cur)
    {
        if(cur->lson==null || cur->rson==null)  return;
        if(cur->lson->w>cur->rson->w*ratio)
        {
            cur->rson=merge(cur->lson->rson,cur->rson);
            pool[--tot]=cur->lson;
            cur->lson=cur->lson->lson;
        }
        if(cur->rson->w>cur->lson->w*ratio)
        {
            cur->lson=merge(cur->lson,cur->rson->lson);
            pool[--tot]=cur->rson;
            cur->rson=cur->rson->rson;
        }
    }
public:
    void insert(node *cur,citem val)
    {
        if(cur->w==1)
        {
            cur->lson=newnode(null,null,min(cur->val,val),1);
            cur->rson=newnode(null,null,max(cur->val,val),1);
        }
        else if(val<=cur->lson->val)    insert(cur->lson,val);
        else    insert(cur->rson,val);
        pushup(cur);
        maintain(cur);
    }
    void erase(node *cur,citem val)
    {
        if(cur->lson->w==1 && cur->lson->val==val)
        {
            pool[--tot]=cur->lson;pool[--tot]=cur->rson;
            *cur=*cur->rson;
        }
        else if(cur->rson->w==1 && cur->rson->val==val)
        {
            pool[--tot]=cur->rson;pool[--tot]=cur->lson;
            *cur=*cur->lson;
        }
        else if(val<=cur->lson->val)  erase(cur->lson,val);
        else    erase(cur->rson,val);
        pushup(cur);
        maintain(cur);
    }
    int rank(node *cur,citem val)
    {
        if(cur->w==1)   return cerr<<"**"<<val.cnt<<' '<<val.rec<<endl,1;
        if(val<=cur->val)   return rank(cur->lson,val);
        return cur->lson->w+rank(cur->rson,val);
    }
    inline void reset(void)
    {
        memset(tr,0,sizeof(tr));
        for(int i=0;i<(MAXN<<1);i++)    pool[i]=&tr[i];
        root=new node(null,null,item(0,UINT_MAX),1);
    }
}t;

int main()
{
    #ifndef ONLINE_JUDGE
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    #endif
    null=new node(nullptr,nullptr,item(0,0),0);
    int T;read(T);
    while(T--)
    {
        t.reset();
        read(m,n,seed);
        for(uint i=1;i<=m;i++)
        {
            a[i]=item{0,0};
            t.insert(root,a[i]);
        }
        for(uint i=1;i<=n;i++)
        {
            cuint ria=randnum(seed,last,m),rib=randnum(seed,last,m);
            cerr<<ria<<' '<<rib<<endl;
            t.erase(root,a[ria]);
            a[ria]+=item(1,rib);
            t.insert(root,a[ria]);
            cerr<<"rank:"<<t.rank(root,a[ria])<<endl;
            last=t.rank(root,a[ria])-1;
            printf("%d\n",last);
        }
        delete root;
    }
    return 0;
}
2020/11/20 22:19
加载中...