P1168 中位数
Posted garen-wang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1168 中位数相关的知识,希望对你有一定的参考价值。
splay水题。。。
本来我一看上去是懵的。脑(fan)洞(le)大(ti)开(jie)发现可以用splay来做。
构造一颗按大小排序的splay,每当弄进奇数个的时候就求一下第k大就行了。
只不过这些东西是可重的,要写一个cnt,别的没了。
代码:
#include<cstdio>
const int maxn = 100005;
int size[maxn], ch[maxn][2], fa[maxn], val[maxn], cnt[maxn];
int tot;
int n;
struct Splay
{
int root;
int dir(int x)
{
return ch[fa[x]][1] == x;
}
void connect(int son, int f, int k)
{
fa[son] = f;
ch[f][k] = son;
}
void pushup(int x)
{
size[x] = size[ch[x][0]] + size[ch[x][1]] + cnt[x];
}
void rotate(int x)
{
int y = fa[x];
int z = fa[y];
int yk = dir(x);
int zk = dir(y);
int b = ch[x][yk ^ 1];
connect(b, y, yk);
connect(y, x, yk ^ 1);
connect(x, z, zk);
pushup(y);
pushup(x);
}
void splay(int x, int goal)
{
while(fa[x] != goal)
{
int y = fa[x];
int z = fa[y];
if(z != goal) dir(x) == dir(y) ? rotate(y) : rotate(x);
rotate(x);
}
if(goal == 0) root = x;
}
void insert(int x)
{
int now = root, f = 0;
while(now && val[now] != x)
{
f = now; now = ch[now][x > val[now]];
}
if(now) cnt[now]++;
else
{
now = ++tot;
fa[now] = f; if(f) ch[f][x > val[f]] = now;
size[now] = 1; cnt[now] = 1; val[now] = x;
}
splay(now, 0);
}
int kth(int k)
{
int now = root;
while(233)
{
if(size[ch[now][0]] + cnt[now] < k)
{
k -= size[ch[now][0]] + cnt[now];
now = ch[now][1];
}
else if(size[ch[now][0]] >= k) now = ch[now][0];
else return now;
}
}
int zhongweishu()
{
return val[kth(size[root] / 2 + 1)];
}
} s;
int read()
{
int ans = 0, s = 1;
char ch = getchar();
while(ch > ‘9‘ || ch < ‘0‘){ if(ch == ‘-‘) s = -1; ch = getchar(); }
while(ch >= ‘0‘ && ch <= ‘9‘) ans = (ans << 3) + (ans << 1) + ch - ‘0‘, ch = getchar();
return s * ans;
}
int main()
{
n = read();
for(int i = 1; i <= n; i++)
{
int temp = read();
s.insert(temp);
if(i % 2) printf("%d
", s.zhongweishu());
}
return 0;
}
以上是关于P1168 中位数的主要内容,如果未能解决你的问题,请参考以下文章