题意:
多次操作,每次增加一个数字,求数字个数为奇数时的区间中位数
解法:
平衡树模板题。
还能删除数字,求前驱后继排名
代码:
#include <bits/stdc++.h>
#define ll long long
#define sc scanf
#define pr printf
using namespace std;
const int MAXN = 1e4 + 5;
const ll inf = 1e9 + 7;
struct node
{
int val;//权值
int sz;//子树大小
int ch[2];//左右儿子
int cnt;//该权值个数
int data;//随机数(用来平衡二叉树)
}treap[MAXN];
int cnt, root;
int newnode(int val)
{
treap[cnt].val = val;
treap[cnt].sz = 1;
treap[cnt].ch[0] = treap[cnt].ch[1] = 0;
treap[cnt].cnt = 1;
treap[cnt].data = rand();
return cnt++;
}
void up(int rot)
{
treap[rot].sz = treap[treap[rot].ch[0]].sz + treap[treap[rot].ch[1]].sz + treap[rot].cnt;
}
void build()
{
cnt = 1;
newnode(INT_MIN); newnode(INT_MAX);
root = 1;
treap[1].ch[1] = 2;
up(1);
}
void rotate(int& rot, int op)
{
int t = treap[rot].ch[op ^ 1];
treap[rot].ch[op ^ 1] = treap[t].ch[op];
treap[t].ch[op] = rot;
rot = t;
up(treap[rot].ch[op]);
up(rot);
}
void insert(int& rot, int val)
{
if (rot == 0)
{
rot = newnode(val);
return;
}
if (treap[rot].val > val)
{
insert(treap[rot].ch[0], val);
if (treap[rot].data < treap[treap[rot].ch[0]].data)
rotate(rot, 1);
}
else if (treap[rot].val < val)
{
insert(treap[rot].ch[1], val);
if (treap[rot].data < treap[treap[rot].ch[1]].data)
rotate(rot, 0);
}
else
treap[rot].cnt++;
up(rot);
}
int find(int rot, int val)
{
if (rot == 0)
return -1;
if (treap[rot].val == val)
return rot;
else if (treap[rot].val < val)
return find(treap[rot].ch[1], val);
else
return find(treap[rot].ch[0], val);
}
int getpre(int rot, int val)//求比val小的最大的数字
{
if (rot == 0)
return 1;//最小值
int ans = 1;//答案在bst中的下标
if (treap[rot].val < val)
ans = rot;
if (treap[rot].val < val)
{
int t = getpre(treap[rot].ch[1], val);
if (treap[ans].val < treap[t].val)
ans = t;
}
else
{
int t = getpre(treap[rot].ch[0], val);
if (treap[ans].val < treap[t].val)
ans = t;
}
return ans;
}
int getnex(int rot, int val)//求比val大的最小的数字
{
if (rot == 0)
return 2;//最大值
int ans = 2;
if (treap[rot].val > val)
ans = rot;
if (treap[rot].val <= val)
{
int t = getnex(treap[rot].ch[1], val);
if (treap[ans].val > treap[t].val)
ans = t;
}
else
{
int t = getnex(treap[rot].ch[0], val);
if (treap[ans].val > treap[t].val)
ans = t;
}
return ans;
}
void delet(int& rot, int val)
{
if (rot == 0)
return;
if (treap[rot].val == val)
{
if (treap[rot].cnt != 1)
treap[rot].cnt--;
else if (treap[rot].ch[0] || treap[rot].ch[1])
{
//判断左旋还是右旋,将需要删除的节点旋转到叶子节点
if (treap[rot].ch[1] == 0 || treap[treap[rot].ch[0]].data > treap[treap[rot].ch[1]].data)
{
rotate(rot, 1);
delet(treap[rot].ch[1], val);
}
else
{
rotate(rot, 0);
delet(treap[rot].ch[0], val);
}
}
else
rot = 0;
}
else if (treap[rot].val > val)
delet(treap[rot].ch[0], val);
else
delet(treap[rot].ch[1], val);
up(rot);
}
int numrank(int rot, int val)
{
if (rot == 0)
return 0;
if (treap[rot].val == val)
return treap[treap[rot].ch[0]].sz + 1;
else if (treap[rot].val > val)
return numrank(treap[rot].ch[0], val);
else
return treap[treap[rot].ch[0]].sz + treap[rot].cnt + numrank(treap[rot].ch[1], val);
}
int kthnum(int rot, int k)
{
if (k <= treap[treap[rot].ch[0]].sz)
return kthnum(treap[rot].ch[0], k);
else if (k > treap[treap[rot].ch[0]].sz + treap[rot].cnt)
return kthnum(treap[rot].ch[1], k - (treap[treap[rot].ch[0]].sz + treap[rot].cnt));
else
return rot;
}
int main()
{
int T;
sc("%d", &T);
while (T--)
{
int op, n;
sc("%d%d", &op, &n);
build();
pr("%d %d\n", op, n / 2 + 1);
vector<int>v;
for (int i = 1; i <= n; i++)
{
int t;
sc("%d", &t);
insert(root, t);
if (i & 1)
{
v.push_back(treap[kthnum(root, i / 2 + 1 + 1)].val);
}
}
for (int i = 0; i < v.size(); i++)
{
pr("%d", v[i]);
if (i == v.size() - 1)
continue;
if (i % 10 == 9)
pr("\n");
else
pr(" ");
}
if (T)
pr("\n");
}
} 
京公网安备 11010502036488号