N 年未打 Splay 玄关求调
查看原帖
N 年未打 Splay 玄关求调
1296826
lcfollower楼主2025/7/19 17:29

rt。

# include <bits/stdc++.h>

# define up(i ,x ,y) for (int i = x ; i <= y ; i ++)
# define dn(i ,x ,y) for (int i = x ; i >= y ; i --)
# define inf 1e9

using namespace std;

inline int read (){int s = 0 ; bool w = 0 ; char c = getchar () ; while (!isdigit (c)) {w |= (c == '-') ,c = getchar () ;} while (isdigit (c)){s = (s << 1) + (s << 3) + (c ^ 48) ; c = getchar ();}return w ? -s : s;}
inline void write (int x){if (x < 0) putchar ('-') ,x = -x; if (x > 9) write (x / 10) ; putchar (x % 10 | 48);}
inline void writesp (int x){write (x) ,putchar (' ');}
inline void writeln (int x){write (x) ,putchar ('\n');}

typedef unsigned int ui ;
ui random ( ui& seed , ui last , const ui m){ 
    seed = seed * 17 + last ; return seed % m + 1; 
}

const int N = 5e5 + 5;
int n ,sum[N] ,tim[N] ,rt ,idx;
ui seed ,m ,lst = 7;
int rubbish[N] ,tp;
struct SPLAY {
  int ch[2] ,p ,sz ,cnt;
  pair <int ,int> val;
}tr[N];
inline void pushup (int u){
  tr[u].sz = tr[tr[u].ch[0]].sz + tr[tr[u].ch[1]].sz + tr[u].cnt;
} inline void rotate (int x){
  int y = tr[x].p ,z = tr[y].p;
  bool k = tr[y].ch[1] == x;
  tr[z].ch[tr[z].ch[1] == y] = x ,tr[x].p = z;
  tr[y].ch[k] = tr[x].ch[k ^ 1] ,tr[tr[x].ch[k ^ 1]].p = y;
  tr[x].ch[k ^ 1] = y ,tr[y].p = x;
  pushup (y) ,pushup (x);
} inline void splay (int x ,int goal){
  while (tr[x].p ^ goal) {
    int y = tr[x].p ,z = tr[y].p;
    if (z ^ goal){
      if ((tr[y].ch[1] == x) ^ (tr[z].ch[1] == y)) rotate (x);
      else rotate (y);
    }
    rotate (x);
  } if (!goal) rt = x;
} inline int newnode (){
  if (!tp) return ++ idx;
  else {int q = rubbish[tp] ;-- tp ; return q;}
} inline int pre (pair <int ,int> x){
  int now = rt;
  now = tr[rt].ch[0];
  while (tr[now].ch[1]) now = tr[now].ch[1];
  return now;
} inline int suc (pair <int ,int> x){
  int now = rt;
  now = tr[rt].ch[1];
  while (tr[now].ch[0]) now = tr[now].ch[0];
  return now;
} inline void del (pair <int ,int> x){
  int l = pre (x) ,r = suc (x);
  splay (l ,0) ,splay (r ,l);
  int u = tr[r].ch[0];
  if (tr[u].cnt > 1) -- tr[u].cnt ,pushup (r) ,pushup (l) ,splay (u ,0);
  else {
    tr[u].cnt = tr[u].p = tr[u].ch[0] = tr[u].ch[1] = 0 ;
    tr[u].val = {0 ,0};
    rubbish[++ tp] = u;
    tr[r].ch[0] = 0;
    pushup (r) ,pushup (l);
  }
} inline void insert (pair <int ,int> x){
  int l = pre (x) ,r = suc (x);
  splay (l ,0) ,splay (r ,l);
  int u = tr[r].ch[0];
  if (!u) {
    u = newnode ();
    tr[u].cnt = tr[u].sz = (abs(x.first) == inf ? 0 : 1);
    tr[u].val = x;
  } else ++ tr[u].cnt;
  pushup (r) ,pushup (l) ,splay (u ,0);
} inline void solve (){
  m = read () ,n = read () ,seed = read ();
  rt = idx = tp = 0;
  up (i ,1 ,n) sum[i] = tim[i] = 0;
  insert ({-inf ,inf}) ,insert ({inf ,-inf});

  up (i ,1 ,n) {
    int ria = random (seed ,lst ,m) ,rib = random (seed ,lst ,m);
      // writesp (ria) ,writeln (rib);
    if (sum[ria]) del ({sum[ria] ,-tim[ria]});
    ++ sum[ria] ,tim[ria] += rib;
    insert ({sum[ria] ,-tim[ria]});
    writeln (lst = tr[tr[rt].ch[0]].sz);
      // cout << rt <<endl;
  }
} signed main (){

  int T = read ();
  while (T --) solve ();
  
  return 0;

}
2025/7/19 17:29
加载中...