Tree

Tree

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

Tree

题目大意:

  • 首先,我们有次操作
  • 操作:在节点下面再加一个权值为的点
  • 操作:询问从点开始往上走,(每次遇到权值大于当前选过的最后一个点的点必定会选),问最多能选多少点

分析

我们可以很容易的发现,我们选中的点一定是一个单调不下降序列

那么就是说,我们可以稍微改动一下操作一,让每一条链都一定是单调不上升的(从根出发的链)

然后,我们每次加入的点必定不会是已经存在的某个点的祖先,所以我们改变他的位置对原来的树是没有影响的

若有节点成为了这个被我们认为操作的节点的儿子,它的值依赖于我们人为操作的那个点,所以这个答案也不会因为我们的操作出现问题

那么我们就可以在加入节点的时候,找到第一个权值大于该节点的点做为这个点的父节点

顺便跟新一下前缀和

这个用倍增实现就好了

inline void AddPoint(ll u, ll p)
{
    ll v = ++cnt;
    wight[v] = p;
    if (wight[u] >= wight[v]) {
        father[v][0] = u;
    } else {
        for (ll i = 19; ~i; --i)
            if (wight[father[u][i]] < wight[v])
                u = father[u][i];
        father[v][0] = father[u][0];
    }
    sum[v][0] = wight[father[v][0]]; 
    for (ll i = 1; i < 20; ++i) {
        father[v][i] = father[father[v][i - 1]][i - 1];
        if (sum[v][i - 1] < inf && father[v][i]) {
            sum[v][i] = sum[v][i - 1] + sum[father[v][i - 1]][i - 1];
        } else break;
    }
}

然后查询的话,能跳就跳,每次向上跳了更新一下限制即可

inline ll Query(ll x)
{
    if (wight[x] > limit) return 0;
    ll ans(1);
    limit -= wight[x];
    for (ll i = 19; ~i; --i)
        if (sum[x][i] <= limit) {
            ans += (1 << i);//向上跳了2的i次方层,那就有2的i次方个点
            limit -= sum[x][i];
            x = father[x][i];
        }
    return ans;
}

Code

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
const ll maxn = 4e5 + 10;
const ll inf = 0x6f6f6f6f6f6f6f6f;

ll father[maxn][20], wight[maxn], cnt(1);
ll sum[maxn][20], lastans, limit;
ll Q, Opt, X, Y;

inline void AddPoint(ll u, ll p)
{
    ll v = ++cnt;
    wight[v] = p;
    if (wight[u] >= wight[v]) {
        father[v][0] = u;
    } else {
        for (ll i = 19; ~i; --i)
            if (wight[father[u][i]] < wight[v])
                u = father[u][i];
        father[v][0] = father[u][0];
    }
    sum[v][0] = wight[father[v][0]]; 
    for (ll i = 1; i < 20; ++i) {
        father[v][i] = father[father[v][i - 1]][i - 1];
        if (sum[v][i - 1] < inf && father[v][i]) {
            sum[v][i] = sum[v][i - 1] + sum[father[v][i - 1]][i - 1];
        } else break;
    }
}

inline ll Query(ll x)
{
    if (wight[x] > limit) return 0;
    ll ans(1);
    limit -= wight[x];
    for (ll i = 19; ~i; --i)
        if (sum[x][i] <= limit) {
            ans += (1 << i);
            limit -= sum[x][i];
            x = father[x][i];
        }
    return ans;
}

inline ll Read()
{
    ll x(0);
    char o(getchar());
    while (o < '0' || o > '9') o = getchar();
    for (; o >= '0' && o <= '9'; o = getchar()) x = (x << 1) + (x << 3) + (o ^ 48);
    return x;
}

int main()
{
    memset (sum, 0x6f, sizeof sum);
    wight[0] = inf;
    Q = Read();
    while (Q--)
    {
        Opt = Read(), X = Read() ^ lastans, Y = Read() ^ lastans;
        if (Opt == 1) AddPoint(X, Y);
        else limit = Y, printf ("%lld\n", lastans = Query(X));
    }
    system("pause");
}
有的没的 文章被收录于专栏

RT,有的没的

全部评论

相关推荐

暴杀流调参工作者:春招又试了一些岗位,现在投递很有意思,不仅要精心准备简历,投递官网还得把自己写的东西一条一条复制上去,阿里更是各个bu都有自己的官网,重复操作无数次,投完简历卡完学历了,又该写性格测评、能力测评,写完了又要写专业笔试,最近还有些公司搞了AI辅助编程笔试,有些还有AI面试,对着机器人话也听不明白录屏硬说,终于到了人工面试又要一二三四面,小组成员面主管面部门主管面hr面,次次都没出错机会,稍有不慎就是挂。 卡学历卡项目卡论文卡实习什么都卡,没有不卡的😂
点赞 评论 收藏
分享
昨天 11:02
已编辑
北方民族大学 全栈开发
“无名小卒,还是名扬天下?”我知道很多人都不觉得我能走到今天这一步,当然,也包括我自己。在我的人生里,有两部作品刻下了最深的烙印:《斗破苍穹》与《龙族》。它们总被人拿来对照:一边是萧炎的桀骜轻狂,一边是路明非的怯懦衰颓。有人说,天蚕土豆没见过魂天帝,但江南见过真凯撒。我时常觉得,自己就是那个衰小孩路明非。可路明非可以开挂,我不可以;我也无数次幻想过,能拥有萧炎那般年少轻狂的人生,可我没有他与生俱来的逆天天赋。我只是个平庸的普通人,一个看过《斗破苍穹》却开不了挂的路明非,只能一步一步往上爬。从我下定决心找实习的那一刻起,我就给自己定下了目标:“我一定要为字节跳动卖命.jpg”。萧炎有他的三年之约,我有我的两年半之约(其实是一年半)。2024.11.20,科大讯飞的第一封实习offer落进邮箱,我迈出了这场奔赴的第一步。2025.8.18,放弃百度转正的安稳机会,转身走进前路未卜的不确定里。我很感谢我在百度的mentor,是她从茫茫人海选中了我,给了我大厂实习的机会。即便有段时间我状态差、产出不理想,她依旧愿意认可我、希望我留下转正。2025.11.14,我选择走进字节跳动,以实习生的身份重新出发。2026.3.25&nbsp;-&nbsp;3.31,一周速通上海飞书,幸遇赏识我的伯乐,斩获Special&nbsp;Offer。被告知面试通过的那一刻,我的内心无比平静,就像这个offer本就该属于我。不是侥幸,是应得的。这一路,有人看轻过我的出身,不相信我能走到这里;也有人在我看不见前路的时候,替我举过灯。没有他们的鼓励与支撑,就没有今天站在这里的我。我看到了自强不息的激荡,那是一个双非的伟大乐章!我是雨夜迈巴赫,我要开启属于我的新篇章了。
在看牛客的本杰明很勇...:真心祝贺l总 我永远的偶像 我滴神
春招至今,你收到几个面试...
点赞 评论 收藏
分享
评论
4
3
分享

创作者周榜

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