Greatest Parents Ligh OJ1128

其实倍增可以”缩”

题意:

一棵树的点权会给你,每一次询问一个x,y 问在x的祖先之中(包括x) 权值 >=y的而且是离x最远的点的编号!

思路

核心的什么也不说了,只是希望说一说这个:
每一次倍增,dp[i][j]~dp[i][0]其实就是相当于是一个二分搜索的过程呢!
比如dp[i][3]会符合答案,那么i就会自动”跳”到 i+2^3的地方,继续在(i+2^3)的地方2^2
一直下去,于是就有了答案!

代码:

#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define N 100005
#define M 20
using namespace std;
int T, n, m, x, y, val[N]={1}, fa[N][M], dp[N][M];
vector<int> G[N];
void DFS(int now)
{
    for (int i = 0; i < G[now].size(); i++)
    {
        int v = G[now][i];
        fa[v][0] = now, dp[v][0] = val[v];
        for (int j = 1; j < M; j++)
            fa[v][j] = fa[fa[v][j - 1]][j - 1];
        for (int j = 1; j < M; j++)
            dp[v][j] = max(dp[v][j - 1], dp[fa[v][j - 1]][j - 1]);
        DFS(v);
    }
}
inline int solve(int x, int y)
{
    for (int i = M-1; i >= 0; i--)
        if (dp[fa[x][i]][i] >= y)
            x = fa[x][i];
    return x;
}
int main()
{
    scanf("%d", &T);
    for (int loc = 1; loc <= T; loc++)
    {
        scanf("%d%d", &n, &m);
        for (int i = 0; i <= n; i++)
            G[i].clear(), fa[0][i] = 0, dp[0][i] = 1;
        for (int i = 1; i < n; i++)
        {
            scanf("%d%d", &x, &val[i]);
            G[x].push_back(i);
        }
        DFS(0);
        printf("Case %d:\n", loc);
        for (int i = 1; i <= m; i++)
        {
            scanf("%d%d", &x, &y);
            printf("%d\n", solve(x, y));
        }
    }
    return 0;
}
### GREATEST 函数的使用方法 #### Oracle 数据库中的 GREATEST 函数 在 Oracle 数据库中,`GREATEST()` 是一种内置函数,用于比较多个表达式的值并返回其中的最大值。它可以接受任意数量的参数,并从中找出最大的那个[^3]。 例如,在以下 SQL 查询中: ```sql SELECT GREATEST(5, 10) FROM DUAL; ``` 此语句会返回 `10`,因为它是在两个输入值(5 和 10)之间的较大者。 如果我们将这个逻辑扩展到字符串或其他数据类型的比较上,则可以像这样操作: ```sql SQL> SELECT GREATEST('A', 'B', 'C', 'D', 'E', 'F', 'G') AS MAX_VALUE FROM DUAL; ``` 上述查询将基于字母顺序返回 `'G'`,即按字典序排列后的最大字符[^1]。 #### GaussDB (DWS) 中的行为差异 尽管许多现代关系型数据库都提供了类似的 `GREATEST()` 功能,但在不同的兼容模式下可能会表现出细微的区别。比如,在 GaussDB 的 MySQL 兼容模式里,某些特定场景可能导致结果不一致或者需要额外注意语法上的调整[^2]。 对于实际应用而言,当跨平台迁移涉及此类功能时,建议仔细阅读官方文档来确认是否存在潜在陷阱以及如何规避它们。 #### 常见错误示例分析 需要注意的是,虽然 `GREATEST()` 可以很好地处理单行内的多字段对比需求,但它并不适用于直接参与分组统计之后的操作。如下所示尝试过滤掉那些计数小于等于四的商品分类将会失败: ```sql select category_id ,count(*) from product group by category_id where count(*) >4 ; -- 错误提示:WHERE 子句不允许聚合函数 ``` 这是因为标准 SQL 要求先完成 GROUP BY 处理后再做进一步筛选工作,因此应该改用 HAVING 来代替 WHERE 实现同样的目的[^5]。 --- ### 示例代码展示 以下是几个关于如何正确运用 `GREATEST()` 的例子: - **获取三列数值里的最高分数** ```sql SELECT student_name, score_math, score_english, score_science, GREATEST(score_math, score_english, score_science) as highest_score FROM students_scores; ``` - **判断日期列表中最晚发生的一个时间点** ```sql SELECT employee_id, hire_date, last_promotion_date, termination_date, GREATEST(hire_date, last_promotion_date, termination_date) as latest_event FROM employees_info; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值