[LightOJ 1128]Greatest Parent

原题链接:http://www.lightoj.com/volume_showproblem.php?problem=1128

原题是英文题面,大概翻译了一下:

最大的祖先

树是一个连通的无环图,在这个问题中给出一个有根树,每个点有一个权值,每个点的权值严格的大于它父亲的权值。现在给出一个点以及一个整数的询问,你需要找到这个点最大的可能的祖先(也许可能包括这个点),它的权值大于或等于给出的整数。

输入

输入的开始是一个整数 T (T≤ 5), 表示测试数据的数量。

每一个情况的第一行是一个空行,下一列读入两个整数 N (1 ≤ N ≤ 105)q (1 ≤ q ≤ 50000) N表示点的个数,q表示询问的个数。点的标记从0到N-1。

然后将会有N-1行,第i行 (1 ≤ i < N) 包括两个整数 pi 和 si (0 ≤ pi < i, 1 ≤ si < 231)pi 表示这个点的父亲,si 表示这个点的权值。假设给出的树是正确的然后下面的限制是存在的。你可以假设第0个点为根节点并且它的点权为1。

以下q行每行包括一个询问,每个询问包括两个整数k和v (1 ≤ k < N, 1 ≤ v ≤ sk).

输出

对于每个情况,在一行输出情况编号,然后对于每个询问,输出最大的,点权大于等于v的祖先的编号k。你可以假设解是存在的。.


样例输入


样例输出


1

7 4

0 3

0 4

0 2

1 4

2 7

2 10

5 1

4 2

5 4

6 10


Case 1:

0

1

2

6

  因为是英文题面,在看题的时候难免有所疏漏或者理解错误,尤其是输入输出格式(之前因为要输出caseWA了n次)。一旦我们知道了输入输出格式,在仔细看题就不是特别复杂了。给出的这棵树满足儿子节点的点权一定比父亲大,那么我们可以利用倍增的思想解决问题,让x按照倍增方式不断向上爬,每爬到一个点就看看这个点的点权和询问的数相比哪个大,满足条件输出结果。如果不是倍增,一步一步向上复杂度为O(n),会被卡,而倍增为O(logn),可以通过。

参考代码

#include<cstdio>
#include<cmath>
#include<cstring>
#define ll int
#define N 200010
#define mm(a) memset(a,0,sizeof(a))
ll read()
{
    char ch = getchar();
    ll x = 0, f = 1;
    while(ch < ‘0‘ || ch > ‘9‘)
    {
        if(ch == ‘-‘) f = -1;
        ch = getchar();
    }
    while(‘0‘ <= ch && ch <= ‘9‘)
    {
        x = (x << 3) + (x << 1) + ch - ‘0‘;
        ch = getchar();
    }
    return x * f;
}//快读
ll head[N],nxt[N],to[N],val[N],fa[N][31],dis[N];
ll t,n,q,cnt;
void reset()
{
    mm(head);
    mm(to);
    mm(val);
    mm(fa);
    mm(dis);
    cnt = 0;
}
void add(ll u,ll v)
{
    cnt++;
    nxt[cnt] = head[u];
    head[u] = cnt;
    to[cnt] = v;
}
void dfs(ll u,ll pa)
{
    for(ll i = 1;i <= 20;i++)
    {
        fa[u][i] = fa[fa[u][i - 1]][i - 1];//预处理出所有的祖先
    }
    for(ll i = head[u];i;i = nxt[i])
    {
        dfs(to[i],u);
    }
}
ll f(ll x,ll num)
{
    for(ll i = 20;i >= 0;i--)
    {
        if(val[fa[x][i]] >= num)
        x = fa[x][i];//倍增往上爬
    }
    return x;
}
int main()
{
    t = read();
    for(int i = 1;i <= t;i++)
    {
        reset();
        val[0] = 1;
        dis[0] = 1;
        n = read();q = read();
        for(ll i = 1;i <= n - 1;i++)
        {
            ll p = read(),s = read();
            add(p,i);
            fa[i][0] = p;
            val[i] = s;
        }
        dfs(0,0);
        printf("Case %d:\n",i);//这句话非常关键QAQ
        while(q--)
        {
            ll k = read(),v = read();
            printf("%d\n",f(k,v));
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/lijilai-oi/p/10691617.html

时间: 2024-09-30 03:34:53

[LightOJ 1128]Greatest Parent的相关文章

1128 - Greatest Parent---LightOj(LCA+离线算法)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1128 给你一颗树,树的每个节点都有一个权值,树根是节点0,权值为1,树中每个节点的权值都是大于父节点的权值的: 然后给出每个节点的父节点以及该节点的权值:有Q个询问,每个询问有两个数u和val,求u的祖先中权值>=val的最大祖先,就是离u最远的那个>=val的祖先的节点: 数的范围较大有5w个Q,1w个n,所以我们不能直接模拟,也许这1w个节点是一串下来的,那么复杂度就变成了nQ

LightOJ - 1128 (倍增法 + dp)

唔 已经有一个多月没有写题解了, 其实这一个多月也是做了一些题目的,但是就是比较懒啊,所以都堆在一起没有写了--. 题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26842 题意: 给出一棵树(有默认根), 每个节点有一个权值,再给出q个询问,每个询问包含v k两个变量, 让你输出树根和v节点的路径上,权值大于等于k的离树根最近的节点. 思路: 算是倍增法 + dp的入门练习吧. dp[v][i] 表示节点v

关于js中window.location.href,location.href,parent.location.href,top.location.href的用法

关于js中window.location.href,location.href,parent.location.href,top.location.href的用法 "window.location.href"."location.href"是本页面跳转. "parent.location.href" 是上一层页面跳转. "top.location.href" 是最外层的页面跳转. 举例说明: 如果A,B,C,D都是html,D

Js中的window.parent ,window.top,window.self详解

在应用有frameset或者iframe的页面时,parent是父窗口,top是最顶级父窗口(有的窗口中套了好几层frameset或者iframe),self是当前窗口, opener是用open方法打开当前窗口的那个窗口. window.self 功能:是对当前窗口自身的引用.它和window属性是等价的. 语法:window.self 注:window.self.window.self是等价的. window.top 功能:返回顶层窗口,即浏览器窗口. 语法:window.top 注:如果窗

LightOJ 1030 Discovering Gold【概率】

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1030 题意:基础概率题. 代码: #include <stdio.h> #include <string.h> #include <vector> #include <string> #include <algorithm> #include <iostream> #include <iterator>

spring中使用parent属性来减少配置

在基于spring框架开发的项目中,如果有多个bean都是一个类的实力,如配置多个数据源时,大部分配置的属性都一样,只有少部分不一样,经常是copy上一个的定义,然后修改不一样的地方.其实spring bean定义也可以和对象一样进行继承. 示例如下:  <bean id="testBeanParent"  abstract="true"  class="com.wanzheng90.bean.TestBean">         &

LightOJ - 1370 Bi-shoe and Phi-shoe

题目链接:http://lightoj.com/login_main.php?url=volume_showproblem.php?problem=1370 题目大意:给N个数a[i], N <= 1e6,问使 Φ(x) >= a[i] 成立的最小x的所有x的和是多少. 解题思路:我们知道的是对于素数 m 来说,phi[m] = m - 1.另一方面,对于一个合数 m 来说, phi[m] < phi[x] , x > m && x 是素数. 因此,我们可以认为,每

lightoj 1057 - Collecting Gold(状压dp)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1057 题解:看似有点下记忆话搜索但是由于他是能走8个方向的也就是说两点的距离其实就是最大的x轴或y轴的差.然后只有15个藏金点状压一下加dfs就行了. #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #define inf 0X3f3f3f

1128: 零起点学算法35——再求多项式(含浮点)

1128: 零起点学算法35--再求多项式(含浮点) Time Limit: 1 Sec  Memory Limit: 64 MB   64bit IO Format: %lldSubmitted: 2141  Accepted: 1002[Submit][Status][Web Board] Description 输入一个整数n,计算 1+1/(1-3)+1/(1-3+5)+...+1/(1-3+5-...+2n-1)的值 Input 输入一个整数n(多组数据) Output 出1+1/(1