洛谷 P11375:[GESP202412 六级] 树上游走

【题目来源】
https://www.luogu.com.cn/problem/P11375

【题目描述】
小杨有一棵包含
无穷节点的二叉树(即每个节点都有左儿子节点和右儿子节点;除根节点外,每个节点都有父节点),其中根节点的编号为 1,对于节点 i,其左儿子的编号为 2×i,右儿子的编号为 2×i+1。
小杨会
从节点 s 开始在二叉树上移动,每次移动为以下三种移动方式的任意一种:
第 1 种移动方式:如果当前节点存在父亲节点,向上移动到当前节点的父节点,否则不移动;
第 2 种移动方式:移动到当前节点的左儿子;
第 3 种移动方式:移动到当前节点的右儿子。
小杨想知道移动 n 次后自己所处的节点编号。数据保证最后所处的节点编号不超过 10^12

【输入格式】
第一行包含两个正整数 n 和
s,代表移动次数和初始节点编号
第二行包含一个长度为 n 且仅包含大写字母 U、L 和 R 的字符串,代表每次移动的方式,其中 U 代表第 1 种移动方式,L 代表第 2 种移动方式,R 代表第 3 种移动方式。

【输出格式】
输出一个正整数,代表最后所处的节点编号。

【输入样例】
3 2
URR

【输出样例】
7

【说明/提示】
小杨的移动路线为 2→1→3→7。 
对于全部数据,保证有 1≤n≤
10^6,1≤s≤10^12

【算法分析】
● 由于题目陈述的二叉树为“每个节点都有左儿子节点和右儿子节点”,故其为
满二叉树。基于样例的移动示意图如下所示:

● long long 的绝对值最大值约为 ‌9.22×10¹⁸‌(即 2⁶³≈9.22e18)。因此,long long 的数量级明确落在 ‌10¹⁸‌ 次方级别‌。

● 题目只说最后所处的节点编号不超过 10^12,没有说经过的节点编号不超过 10^12,甚至会超过 long long 的范围 10^18 而爆掉。不过据题意,
即便经过的编号超过了 10^12,最终还是会返回编号不超过 10^12 的位置,因此当遇到的编号超过 10^12 时,可无视即不移动

● 若整数大于 2×10^9,就选择使用 long long 型:https://blog.youkuaiyun.com/hnjzsyjyj/article/details/132240042


【算法代码】

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const LL imx=1e12;
LL n,id,cnt;
char ch;

int main() {
    cin>>n>>id;
    while(n--) {
        cin>>ch;
        if(ch=='U') {
            if(cnt!=0) {
                cnt--;
                continue;
            }
            if(id!=1) id=id/2;
        } 
		else if(ch=='L') {
            if(id*2>imx) cnt++;
            else id=id*2;
        } 
		else {
            if(id*2>imx) cnt++;
            else id=id*2+1;
        }
    }
    cout<<id<<endl;
    return 0;
}

/*
in:
3 2
URR

out:
7
*/




【参考文献】
https://blog.youkuaiyun.com/weixin_66461496/article/details/145453051
https://www.luogu.com.cn/problem/solution/P11375
https://blog.youkuaiyun.com/hnjzsyjyj/article/details/147077708



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值