AC代码
#include <cstdio>
#include <cstring>
namespace read
{
unsigned int lst = 7, seed, m;
typedef unsigned int ui ;
ui randNum( ui& seed , ui last , const ui m){
seed = seed * 17 + last ; return seed % m + 1;
}
int read()
{
return randNum(seed, lst, m);
}
}
const int MX = 100010, MXM = 1000010, MXT = MXM * 5;
template <typename T>
struct balTree
{
#define get(x) (son[fa[x]][1] == x)
#define update(x) (siz[x] = siz[son[x][0]] + siz[son[x][1]] + cnt[x])
private:
T val[MXT];
int fa[MXT], son[MXT][2], cnt[MXT], siz[MXT], tot, rt;
void rotate(int x)
{
if (rt == fa[x])
{
rt = x;
}
int ffa = fa[fa[x]], dr = get(x);
son[ffa][get(fa[x])] = x;
fa[son[x][not dr]] = fa[x];
son[fa[x]][dr] = son[x][not dr];
son[x][not dr] = fa[x];
fa[fa[x]] = x;
fa[x] = ffa;
update(son[x][not dr]);
update(x);
}
void splay(int x)
{
while (x != rt)
{
if (fa[x] != rt)
{
rotate(get(x) == get(fa[x]) ? fa[x] : x);
}
rotate(x);
}
}
int find(T x)
{
int p = rt;
while (val[p] != x)
{
p = son[p][val[p] < x];
}
return p;
}
public:
void insert(T x)
{
if (not rt)
{
fa[rt = ++tot] = 0;
}
else
{
int p = rt, pfa;
while (p)
{
if (val[p] == x)
{
cnt[p]++;
update(p);
splay(p);
return;
}
pfa = p;
p = son[p][val[p] < x];
}
son[pfa][val[pfa] < x] = ++tot;
fa[tot] = pfa;
}
val[tot] = x;
cnt[tot] = 1;
son[tot][0] = son[tot][1] = 0;
update(tot);
splay(tot);
}
void del(T x)
{
splay(find(x));
if (cnt[rt] > 1)
{
cnt[rt]--;
update(rt);
}
else if (not son[rt][0] and not son[rt][1])
{
rt = 0;
}
else if (son[rt][0] and son[rt][1])
{
int t = son[rt][1], p = rt = son[rt][0];
fa[rt] = 0;
while (son[p][1])
{
p = son[p][1];
}
splay(p);
son[rt][1] = t;
fa[t] = rt;
update(p);
}
else
{
rt = son[rt][(bool)son[rt][1]];
}
}
int rk(T x)
{
int p = rt, ret = 0;
while (p)
{
if (val[p] <= x)
{
ret += siz[son[p][0]] + (val[p] < x) * cnt[p];
p = son[p][1];
}
else
{
p = son[p][0];
}
}
return ret;
}
void clear()
{
tot = rt = 0;
}
#undef get
#undef update
};
struct part
{
int ac, tim;
void operator+= (int t)
{
ac++;
tim += t;
}
bool operator== (part oth)
{
return ac == oth.ac and tim == oth.tim;
}
bool operator!= (part oth)
{
return not operator== (oth);
}
bool operator< (part oth)
{
return ac == oth.ac ? tim < oth.tim : ac > oth.ac;
}
bool operator<= (part oth)
{
return operator< (oth) or operator== (oth);
}
} a[MX];
balTree <part> tr;
int main()
{
int t, n, m, x, tim;
scanf("%d", &t);
while (t--)
{
scanf("%d%d%d", &n, &m, &read::seed);
read::m = n;
for (int i = 1; i <= n; i++)
{
a[i] = { 0, 0 };
tr.insert(a[i]);
}
while (m--)
{
x = read::read();
tim = read::read();
tr.del(a[x]);
a[x] += tim;
tr.insert(a[x]);
printf("%d\n", read::lst = tr.rk(a[x]));
}
tr.clear();
}
}
其中insert函数当树是空的时会把根的父亲清空,但在函数del中当根只有一个儿子时却不会
如果我在insert中不清空根的父亲,前两个点就会T
为什么会这样