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;
}