P10466 邻值查找 题解
前置知识
解法
笔者写这篇题解的时候题面应该是出锅了,建议去看 Acwing 的题面。
第一问同 luogu P2234 [HNOI2002] 营业额统计 ,平衡树维护前驱、后继(非严格意义上的)求出差值后取 \(\min\) 即可;第二问用 map
实现一个映射即可维护位置。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define sort stable_sort
#define endl '\n'
const ll INF=0x3f3f3f3f3f3f3f3f;
ll rt_sum=0;
map<ll,ll>f;
struct Treap
{
ll son[2],val,rnd,cnt,siz;
}tree[100010];
#define lson(rt) (tree[rt].son[0])
#define rson(rt) (tree[rt].son[1])
#define dson(rt,d) (tree[rt].son[d])
#define ason(rt,d) (tree[rt].son[d^1])
void pushup(ll rt)
{
tree[rt].siz=tree[lson(rt)].siz+tree[rson(rt)].siz+tree[rt].cnt;
}
ll build(ll val)
{
rt_sum++;
lson(rt_sum)=rson(rt_sum)=0;
tree[rt_sum].val=val;
tree[rt_sum].rnd=rand();
tree[rt_sum].cnt=tree[rt_sum].siz=1;
return rt_sum;
}
void rotate(ll &rt,ll d)
{
ll lsrt=ason(rt,d);
ason(rt,d)=dson(lsrt,d);
dson(lsrt,d)=rt;
pushup(rt);
rt=lsrt;
pushup(rt);
}
void insert(ll &rt,ll val)
{
if(rt==0)
{
rt=build(val);
}
else
{
if(tree[rt].val==val)
{
tree[rt].cnt++;
tree[rt].siz++;
}
else
{
ll d=(val>tree[rt].val);
insert(dson(rt,d),val);
if(tree[rt].rnd<tree[dson(rt,d)].rnd)
{
rotate(rt,d^1);
}
pushup(rt);
}
}
}
ll query_pre(ll rt,ll val)
{
if(rt==0)
{
return -INF;
}
if(tree[rt].val<val)
{
return max(tree[rt].val,query_pre(rson(rt),val));
}
else
{
return query_pre(lson(rt),val);
}
}
ll query_lower(ll rt,ll val)
{
if(rt==0)
{
return INF;
}
if(tree[rt].val>=val)
{
return min(tree[rt].val,query_lower(lson(rt),val));
}
else
{
return query_lower(rson(rt),val);
}
}
int main()
{
ll n,x,rt=0,sum1,sum2,i;
srand(time(0));
cin>>n;
for(i=1;i<=n;i++)
{
cin>>x;
if(i>=2)
{
sum1=query_pre(rt,x);
sum2=query_lower(rt,x);
if(x-sum1<sum2-x)
{
cout<<x-sum1<<" "<<f[sum1]<<endl;
}
if(x-sum1==sum2-x)
{
cout<<x-sum1<<" "<<f[min(sum1,sum2)]<<endl;
}
if(x-sum1>sum2-x)
{
cout<<sum2-x<<" "<<f[sum2]<<endl;
}
}
insert(rt,x);
if(f.find(x)==f.end())
{
f[x]=i;
}
}
return 0;
}
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/18238541,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。