CF1006E Military Problem

Military Problem

https://ac.nowcoder.com/acm/problem/112932

题意:给你一棵树,有q次查询,每次查询第n个结点的他的子树按照dfs序第x个元素是什么?

题解:一道dfs序的裸的题目。

首先需要一个数组存放第i个结点在dfs序中的位置
再需要一个数组来存放dfs序的顺序
在需要一个数组来存放一个结点子树的大小。(用来判断是否需要输出-1)

每次查询首先判断他的子树大小是否符合要求
如果符合要求再找到这个结点在dfs序中的位置。
然后利用存放dfs序顺序的数组瞬移 k-1 位,输出此元素即可。
利用这三个数组,即可再O(n)的时间复杂度下解决问题。

/*Keep on going Never give up*/
//#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
#define int long long

#define endl '\n'
#define Accepted 0
#define AK main()
#define I_can signed
using namespace std;
const int maxn =2e5+10;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll mod=1e9+7;

vector<int> edge[maxn];
int num[maxn];
int sum[maxn];
int cnt=0;
vector<int> ans;
int now;
void dfs(int x){
    num[x]=++cnt;
    int t=now;
    ans.push_back(x);
    for(auto i:edge[x]){
        now++;
        dfs(i);
    }
    sum[x]=now-t;
}

signed main(){
    int n,m;
    ios::sync_with_stdio(false);
    cin>>n>>m;
    ans.push_back(-1);
    for(int i=2;i<=n;i++){
        int x;
        cin>>x;
        edge[x].push_back(i);
    }
    dfs(1);
    for(int i=0;i<m;i++){
        int x,k;
        cin>>x>>k;
        int pos=num[x];
        if(k-1>sum[x]) cout<<-1<<endl;
        else
        cout<<ans[pos+k-1]<<endl;
    }
}

题解 文章被收录于专栏

主要写一些题目的题解

全部评论

相关推荐

2025年10月3日中午,在写完定时一年后发给自己的信之后,敲下键盘,写下这篇文字。我把标题的“所有人”加了引号,因为如我们所见,确实有的人顺风顺水,每天过的很开心,或是早早进入大厂,或是年纪轻轻就拿到了高薪offer,或是过着可能我努力十年也不一定实现的生活。但也许,不是每个人的痛苦都能被别人看到的,这个月我经常会哭,被骗6000块钱、手上钱不够导致拖欠房租、生活还要借朋友钱、国庆长假也没有钱去旅游,互联网公司不稳定担心试用期不过(毕竟上段实习就是被裁了,一有点风吹草动就害怕),但这样的我,不是所有人都知道的,居然是有些朋友的羡慕对象。回忆我的七年“长跑”别人都是多年幸福的恋爱长跑,我没有恋...
故事和酒66:让每一颗种子找到合适自己的生长方式,最终绽放出独一无二的花朵,这远比所有人都被迫长成同一棵“参天大树”的世界,更加美好和富有生机。这是社会和环境的问题,而不是我们的问题。然而就是在这样的环境中,楼主依然能突破自我,逆势成长,其中的艰辛可想而知。这一路的苦难终究会化作你成长的养料
你小时候最想从事什么职业
点赞 评论 收藏
分享
评论
2
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务