1 Star 0 Fork 0

南陽劉子驥 / OI Codes

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
p3369_scapegoat.cpp 2.92 KB
一键复制 编辑 原始数据 按行查看 历史
南陽劉子驥 提交于 2022-06-15 14:11 . 20220615
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 100010;
int n;
double alpha = 0.75;
struct Scapegoat
{
int ls, rs;
int w, wn;
int s, sz, sd;
}tr[N];
int cnt, rt;
void calc(int p)
{
tr[p].s = tr[tr[p].ls].s + tr[tr[p].rs].s + 1;
tr[p].sz = tr[tr[p].ls].sz + tr[tr[p].rs].sz + tr[p].wn;
tr[p].sd = tr[tr[p].ls].sd + tr[tr[p].rs].sd + (tr[p].wn != 0);
}
bool canrbu(int p)
{
return tr[p].wn && (alpha * tr[p].s <= ( double )max(tr[tr[p].ls].s, tr[tr[p].rs].s) || ( double )tr[p].sd <= alpha * tr[p].s);
}
int ldr[N];
void rbuunf(int &ldc, int p)
{
if(!p)return;
rbuunf(ldc, tr[p].ls);
if(tr[p].wn)ldr[ldc++] = p;
rbuunf(ldc, tr[p].rs);
}
int rbubld(int l, int r)
{
if(l >= r)return 0;
int mid = (l + r) >> 1;
tr[ldr[mid]].ls = rbubld(l, mid);
tr[ldr[mid]].rs = rbubld(mid + 1, r);
calc(ldr[mid]);
return ldr[mid];
}
void rbuild(int &p)
{
int ldc = 0;
rbuunf(ldc, p);
p = rbubld(0, ldc);
}
void insert(int &p, int k)
{
if(!p)
{
p = ++cnt;
if(!rt)rt = 1;
tr[p].w = k;
tr[p].ls = tr[p].rs = 0;
tr[p].wn = tr[p].s = tr[p].sz = tr[p].sd = 1;
}
else
{
if(tr[p].w == k)tr[p].wn++;
else if(tr[p].w < k)insert(tr[p].rs, k);
else insert(tr[p].ls, k);
calc(p);
if(canrbu(p))rbuild(p);
}
}
void loschn(int &p, int k)
{
if(!p)return;
if(tr[p].w == k)
{
if(tr[p].wn)tr[p].wn--;
}
else
{
if(tr[p].w < k)loschn(tr[p].rs, k);
else loschn(tr[p].ls, k);
}
calc(p);
if(canrbu(p))rbuild(p);
}
int uprbnd(int p, int k)
{
if(!p)
return 1;
else if(tr[p].w == k && tr[p].wn)
return tr[tr[p].ls].sz + tr[p].wn + 1;
else if(tr[p].w > k)
return uprbnd(tr[p].ls, k);
else
return tr[tr[p].ls].sz + tr[p].wn + uprbnd(tr[p].rs, k);
}
int uprgtr(int p, int k)
{
if(!p)
return 0;
else if(tr[p].w == k && tr[p].wn)
return tr[tr[p].ls].sz;
else if(tr[p].w < k)
return tr[tr[p].ls].sz + tr[p].wn + uprgtr(tr[p].rs, k);
else
return uprgtr(tr[p].ls, k);
}
int getk(int p, int k)
{
if(!p)
return 0;
else if(tr[tr[p].ls].sz < k && k <= tr[tr[p].ls].sz + tr[p].wn)
return tr[p].w;
else if(tr[tr[p].ls].sz + tr[p].wn < k)
return getk(tr[p].rs, k - tr[tr[p].ls].sz - tr[p].wn);
else
return getk(tr[p].ls, k);
}
int precrs(int p, int k)
{
return getk(p, uprgtr(p, k));
}
int succsr(int p, int k)
{
return getk(p, uprbnd(p, k));
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
int op, x;
scanf("%d%d", &op, &x);
if(op == 1)
{
insert(rt, x);
}
else if(op == 2)
{
loschn(rt, x);
}
else if(op == 3)
{
int rnk = uprgtr(rt, x) + 1;
printf("%d\n", rnk);
}
else if(op == 4)
{
int k = getk(rt, x);
printf("%d\n", k);
}
else if(op == 5)
{
int pre = precrs(rt, x);
printf("%d\n", pre);
}
else if(op == 6)
{
int suc = succsr(rt, x);
printf("%d\n", suc);
}
}
return 0;
}
1
https://gitee.com/kaiserwilheim/OIcodes.git
git@gitee.com:kaiserwilheim/OIcodes.git
kaiserwilheim
OIcodes
OI Codes
master

搜索帮助