P5338 [TJOI2019]甲苯先生的滚榜

题目

P5338 [TJOI2019]甲苯先生的滚榜

分析

平衡树模板题。查询一个数的排名。

代码

#include<bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T &x){
	x=0;char ch=getchar();bool f=false;
	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	x=f?-x:x;
	return ;
}
template <typename T>
inline void write(T x){
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10^48);
	return ;
}
namespace STD{
    const int N=1e6+5;
    unsigned int t,n,m,seed,lst=7;
    unsigned int randNum(unsigned int& seed , int last , const int m){ 
        seed = seed * 17 + last ; return seed % m + 1; 
    }
    namespace FHQTreap{
        struct Change{
            int num,tim;
            Change(){}
            Change(int num,int tim):num(num),tim(tim){}
            bool operator <=(const Change &b)const{
                return num==b.num?tim<=b.tim:num>b.num;
            }
        }w[N],val[N];
        int siz[N],son[N][2],rnd[N];
        int cnt,rt;
        void clear(){for(int i=1;i<=cnt;i++) son[i][0]=son[i][1]=siz[i]=0,val[i]=Change(0,0);cnt=rt=0;}
        void pushup(int rt){siz[rt]=siz[son[rt][0]]+siz[son[rt][1]]+1;}
        int NewNode(Change x){int u=++cnt;val[u]=x;siz[u]=1;rnd[u]=rand();return u;}
        void split(int tmp,Change x,int &u,int &v){
            if(!tmp){u=0;v=0;return ;}
            if(val[tmp]<=x){u=tmp;split(son[u][1],x,son[u][1],v);pushup(u);}
            else{v=tmp;split(son[v][0],x,u,son[v][0]);pushup(v);}
    	}
        int merge(int x,int y){
            if(!x||!y) return x|y;
            if(rnd[x]<rnd[y]){son[x][1]=merge(son[x][1],y);pushup(x);return x;}
            else{son[y][0]=merge(x,son[y][0]);pushup(y);return y;}
        }
        void del(Change k){
            int x,y,z;Change tmp=k;tmp.tim--;
            split(rt,k,x,z);split(x,tmp,x,y);
            y=merge(son[y][0],son[y][1]);rt=merge(x,merge(y,z));
        }
        void Insert(Change k){
            int x,y;
            split(rt,k,x,y);
            rt=merge(x,merge(NewNode(k),y));
    	}
        unsigned int Query(Change k){
            int x,y;k.tim--;
            split(rt,k,x,y);
            unsigned int res=siz[x];
            rt=merge(x,y);
            return res;
        }
    }
    using namespace FHQTreap;
    void work(){
        read(t);
        while(t--){
            unsigned int a,b;
            clear();read(m),read(n),read(seed);
            for(int i=1;i<=n;i++){
                a=randNum(seed,lst,m);b=randNum(seed,lst,m);del(w[a]);
                w[a].num++;w[a].tim+=b;
                Insert(w[a]);lst=Query(w[a]);
				write(lst),putchar('\n');
            }
            for(int j=1;j<=m;j++) w[j]=Change(0,0);
        }
        return ;
    }
}
int main(){
    STD::work();
    return 0;
}
posted @ 2021-05-17 21:12  __Anchor  阅读(30)  评论(0编辑  收藏  举报