首页 > 其他分享 >P10466 邻值查找 题解

P10466 邻值查找 题解

时间:2024-06-08 12:59:57浏览次数:13  
标签:rt P10466 val 题解 ll tree 邻值 sum define

题目传送门

前置知识

二叉搜索树 & 平衡树

解法

笔者写这篇题解的时候题面应该是出锅了,建议去看 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;
}

标签:rt,P10466,val,题解,ll,tree,邻值,sum,define
From: https://www.cnblogs.com/The-Shadow-Dragon/p/18238541

相关文章

  • P10499 开关问题 题解
    题目传送门前置知识高斯消元法解异或方程组|乘法原理解法把开关的相互影响关系转化成异或,然后就转化成了异或方程组,高斯消元求解即可。判断是否存在解的过程同luoguP2455[SDOI2006]线性方程组。由于自由元仅能取\(0/1\),故总方案数为\(2\)的自由元数量次方。代码......
  • P7219 [JOISC2020] 星座 3 题解
    会发现题目的坐标其实是平面直角坐标系。我们按\(y\)坐标从小到大考虑所有的星星,假设当前考虑到了星星\(i\)。我们先计算出之前所有能够影响到\(i\)的星星的代价和为\(cost\)(可以用树状数组维护)。然后分类讨论。若\(c_i\lecost\),那么肯定直接将\(i\)直接涂黑,因为它更......
  • P10560 [ICPC2024 Xi'an I] The Last Cumulonimbus Cloud 题解
    好好玩的题。思路对于一个图上邻域问题,我们有一个很经典的做法:根号分治。考虑根号分治的本质是什么。我们把点分成两类,平衡每一种点的时间,也就是度数大的与度数小的点。所以对于这道题,我们有了更加好的做法。发现题目给的图的性质就是一个天然的划分方案。我们每次找到图中......
  • P10553 [ICPC2024 Xi'an I] Guess The Tree 题解
    挺有意思的题。思路考虑一个比较自然的做法。我们每次对于一棵树,我们将它的某一条链抽出来。这样,我们只需要知道这颗树的所有节点与链底的\(\text{lca}\),就可以知道它是属于这条链上哪一个节点的下面。然后就可以递归处理。由于交互库不是自适应的。我们可能可以想到随机......
  • P9000 [CEOI2022] Measures 题解
    思路简单题。考虑任意两点之间的限制。任意两点合法时必须要满足:\[\frac{d(j-i)-(a_j-a_i)}{2}\let(i\lej)\]所以答案即为:\[\max_{i\lej}\frac{d(j-i)-(a_j-a_i)}{2}\]使用线段树简单维护即可。时间复杂度:\(O((n+m)\log(n+m))\)。Code#include<bits/stdc++.h>using......
  • CF1192B Dynamic Diameter 题解
    思路静态\(\text{toptree}\)板子题。定义我们使用簇来表示树上的一个连通块。可以按照如下方式定义一个簇:一个簇可以表示为三元组\((u,v,E)\),其中\(u,v\)为树的节点,称为簇的界点,\(E\)为一个边的集合,表示该簇包含的边,路径\((u,v)\)称作簇路径。\(u,v\)分别为上界......
  • 无限之环 题解
    五星压行大师\(lyh\)表示:这是难得能让他的代码长度打破百行大关的题目(182行)。首先,根据科技与狠活,本题可以黑白染色。源点联向白格,黑格连向汇点。发现每个格子都可以连向四个方向,所以可以建立四个点,代表水管连到了上下左右四个方向。设四元组\((x,y,z,p)\)表示水管初始状态......
  • 开车旅行|倍增优化dp+双端列表/set|题解
    题面:题面链接这题的思路值得借鉴,也是我做的第一道倍增优化dp题目.比较好的是题目的意思较为清晰,所以不再赘述.解析:这里我们可以非常直接的想到暴力模拟,因为第一眼看上去前七个点的数据范围是支持我们进行一个简单的预处理得到对应人在对应位置的决策的.(排序O(n×sqrt(......
  • [ABC107D] Median of Medians 题解
    题目大意:一个长度为$M$的序列的中位数为这个序列从小到大排序后第$\lfloor\fracM2\rfloor+1$个数,将这个序列的所有子段的中位数放入一个序列中,求这个序列的中位数。设一个序列$a$的中位数为$x$,那么$a$中至少会有一半的数大于等于$x$,并且$x$是$a$中满足这个条件......
  • プログラミングコンテストチャレンジブック 题解
    题目大意:从$n$根木棒里选出六根拼成两个合法的三角形,使这两个三角形的周长和最大。考虑贪心,证明在后面。首先我们要知道一个三角形基本定理:较短两边长度之和大于最长边。那我们就根据这个定理先去寻找最大三角形的最长边。先排序,然后循环枚举,对于每个$a_i$,可以寻找到的最大......