【每日一题】3月31日

城市网络

http://www.nowcoder.com/questionTerminal/339fee670055486ca7967c53bab7622f

我们考虑一个暴力的做法:每次从这个点找到它上面的第一个比他大的点 跳过去。
但是这样显然是过不了的。我们先丢掉询问给出的那个权 每次就拿这个点上的权来跳 答案如何快速处理。
我们可以倍增: 往上找了 个答案之后的点在哪里。问题转化为处理

这个也可以利用我们前面已经求出的f来计算:观察到 随着 的递增而递增。所以我们可以用类似询问倍增的方式来做:每次枚举 比较 和当前点的权 决定跳不跳。

对于询问 题解里有一个很巧妙的做法:将每个点接在起点的下面就可以了(也可以每一次都先倍增找到第一个比它大的)

#include<bits/stdc++.h>

#define fi first
#define se second
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 5e5 + 5;

struct Edge{
    int to,nxt;
}e[MAXN<<1];
int head[MAXN],cnt;

inline void add(int u,int v){
    e[++cnt] = (Edge){v,head[u]};head[u] = cnt;
    e[++cnt] = (Edge){u,head[v]};head[v] = cnt;
}

int n;
int a[MAXN];
int b[MAXN],dep[MAXN],f[MAXN][20];

inline void dfs(int v,int fa=0){
    int t = fa;
    ROF(i,19,0){
        if(f[t][i] && a[f[t][i]] <= a[v]) t = f[t][i];
    }
    if(a[t] > a[v]) f[v][0] = t;
    else f[v][0] = f[t][0];
    FOR(i,1,19) f[v][i] = f[f[v][i-1]][i-1];
    for(int i = head[v];i;i = e[i].nxt){
        if(e[i].to == fa) continue;
        dep[e[i].to] = dep[v] + 1;dfs(e[i].to,v);
    }
}

int main(){
    int q;scanf("%d%d",&n,&q);
    FOR(i,1,n) scanf("%d",a+i);
    FOR(i,2,n){
        int u,v;scanf("%d%d",&u,&v);add(u,v);
    }
    FOR(i,n+1,n+q){
        int u,v,w;scanf("%d%d%d",&u,&v,&w);
        add(i,u);
        a[i] = w;b[i-n] = v;
    }
    dep[1] = 1;dfs(1,0);
    FOR(i,1,q){
        int ans = 0,v = i+n;
        ROF(k,19,0){
            if(dep[f[v][k]] >= dep[b[i]]){
                ans |= (1<<k);
                v = f[v][k];
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
全部评论

相关推荐

01-28 16:12
中南大学 Java
几年前还没有chatgpt的时候,刷题真的是很痛苦。刷不出来只能看题解,题解有几个问题:第一个是每次看的写题解的人都不一样,很难有一个统一的思路;第二个也是最重要的是,题解只提供了作者自己的思路,但是没有办法告诉你你的思路哪里错了。其实很少有错误的思路,我只是需要被引导到正确的思路上面去。所以传统题解学习起来非常困难,每次做不出来难受,找题解更难受。但是现在chatgpt能做很多!它可以这样帮助你&nbsp;-1.&nbsp;可以直接按照你喜欢的语言生成各种解法的题解和分析复杂度。2.&nbsp;把题和你写的代码都发给它,它可以告诉你&nbsp;你的思路到底哪里有问题。有时候我发现我和题解非常接近,只是有一点点🤏想错了。只要改这一点点就是最优解。信心倍增。3.&nbsp;如果遇到不懂的题解可以一行一行询问为什么要这样写,chatgpt不会嫌你烦。有时候我觉得自己的range写错了,其实那样写也没错,只是chat老师的题解有一点优化,这个它都会讲清楚。4.&nbsp;它可以帮你找可以用同类型解法来做的题。然后它可以保持解法思路不变,用一个思路爽刷一个类型的题。如果题目之间思路又有变化,它会告诉你只有哪里变了,其他的地方还是老思路。5.&nbsp;它也可以直接帮你总结模板,易错点。经过chat老师的指导,我最大的改变是敢刷题了。之前刷题需要先找某一个人写的算法题repo,然后跟着某一个人他的思路刷他给的几个题。如果想写别的题,套用思路失败了,没有他的题解,也不知道到底哪里错了;看别人的题解,思路又乱了。这个问题在二分查找和dp类型的题里面特别常见。但是现在有chat老师,他会针对我的代码告诉我我哪里想错了,应该怎么做;还按照我写代码的习惯帮我总结了一套属于我的刷题模板。每天写题全是正反馈!
明天不下雨了:那我建议可以用 chatgpt atlas 或者 dia 去刷,也可以用 chrome 加个 ai 插件去刷 左边刷题右边 chat 效果很好
AI时代的工作 VS 传...
点赞 评论 收藏
分享
02-10 13:41
西南大学 Java
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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