牛客寒假基础补题 —— 第二场

news/2024/7/15 17:18:41 标签: 图论, 算法, c++

link

G.小沙的身法

由于给出的是一个树,所以两点间简单路径唯一。考虑极端情况,给出的n个点构成一条链,可以用前缀和求解,所以容易想到用lca通过类似方法计算。

const int maxn = 1e6 + 10;
int n, m;
int vis2[maxn];
int a[maxn];
int Log2[maxn], fa[maxn][30], dep[maxn];
int head[maxn];
bool vis[maxn];
long long zheng[maxn], fan[maxn];
struct Edge {
    int to, dis = 1, next;
}edge[maxn << 1];
int p;
void add_edge(int u, int v) {
    p++;
    edge[p].to = v;
    edge[p].next = head[u];
    head[u] = p;
}
void dfs(int cur, int fath = 0) {
    if(vis[cur]) return;
    vis[cur] = true;
    zheng[cur] = zheng[fath] + max(0, a[cur] - a[fath]);
    fan[cur] = fan[fath] + max(0, a[fath]-a[cur]);
    dep[cur] = dep[fath] + 1;
    fa[cur][0] = fath;
    for(int i = 1; i <= Log2[dep[cur]]; i++)
        fa[cur][i] = fa[fa[cur][i-1]][i-1];
    for(int i = head[cur]; i; i = edge[i].next)
        dfs(edge[i].to, cur);
}
void init() {
    for(int i = 1; i <= n; i++) {
        dep[i] = 0;
        head[i] = 0;
    }
    p = 0;
    for(int i = 2; i <= n; i++)
        Log2[i] = Log2[i / 2] + 1;
}
int lca(int a, int b) {
    if(dep[a] > dep[b])
        swap(a, b);
    while(dep[a] != dep[b])
        b = fa[b][Log2[dep[b]-dep[a]]];
    if(a == b)
        return a;
    for(int k = Log2[dep[a]]; k >= 0; k--)  //跳跃长度从长到短
        if(fa[a][k] != fa[b][k]) {
            a = fa[a][k];
            b = fa[b][k];
        }
    return fa[a][0];
}
void solve() {
    cin >> n >> m;
    init();
    for(int i = 1; i <= n; i++) cin >> a[i];
    for(int i = 1; i < n; i++) {
        int u, v;
        cin >> u >> v;
        vis2[u]++; vis2[v]++;
        add_edge(u, v);
        add_edge(v, u);
    }
    for(int i = 1; i<= n; i++) {
        if(vis2[i] == 1) {
            dfs(i);
            break;
        }
    }
    while(m--) {
        int u, v;
        cin >> u >> v;
        if(u == v) {
            cout << a[u] << endl;
            continue;
        }
        int l = lca(u, v);
        ll ans = zheng[v] + fan[u] - fan[l] - zheng[l] + a[u];
        cout << ans << endl;
    }
}

http://www.niftyadmin.cn/n/1764913.html

相关文章

牛客寒假基础补题 —— 第三场

这场因为收拾东西准备回家所以没有打,刚刚回家了补一下。 B.智乃买瓜 背包 int n, m; int w[maxn]; int dp[maxm]; void solve() {cin >> n >> m;dp[

NSTimer类的使用

创建一个 Timer scheduledTimerWithTimeInterval: invocation: repeats: (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo; scheduledTimerWithTimeInterval: target: selector: userInfo: …

P3403 跳楼机 同余最短路

P3403 思路 同余最短路 dis[i]表示仅通过2,3操作能够达到的 a mod x i 的最小的a值 注意由于起始位置在1处&#xff0c;故dis[1] 1 代码 // // #include <bits/stdc.h> using namespace std; //#define mp make_pair #define pii pair<int,int> #define pb p…

hbuilder egit插件的安装使用--项目文件丢失的教训

http://blog.csdn.net/u011871921/article/details/44238971转载于:https://www.cnblogs.com/zhaoyanjun/p/4583522.html

P2371 [国家集训队]墨墨的等式 ——同余最短路

P2371 思路 同余最短路&#xff0c;自我感觉做这类题要注意两点。 1.虽然n的范围很小&#xff0c;但实际建图的点的数量为min{a_i} 5e5&#xff0c;边的数量为n∗ain * a_in∗ai​即12*5e5。 2.和上篇文章的题目初始dis[1] 1不同&#xff0c;这道题目初始值即为dis[0] 0,表…

切换用户后whoami打印用户的问题

问题&#xff1a; 为何第二个whoami打印的还是root&#xff1f; rootlocalhost /]# [rootlocalhost /]# [rootlocalhost /]# more test.sh #!/bin/bashecho "current user is $(whoami)"su - oracle <<!echo "current user is $(whoami)"whoami[root…

acwing346走廊泼水节—— MST *

Link 思路 感觉方法很妙的一道题&#xff0c;用类似kruskal的方法&#xff0c;每次合并两个联通块x, y时&#xff0c;假设这条边长度为 www&#xff0c;若要构成完全图&#xff0c;则我们需要额外添加SxSy−1S_xS_y-1Sx​Sy​−1条边&#xff0c;其中SiS_iSi​表示第 iii 个连…

acwing349 黑暗城堡 ——最短路径生成树

Link 思路 最短路径生成树计数 代码 // // #include <bits/stdc.h> using namespace std; //#define mp make_pair #define pii pair<int,int> #define pb push_back #define ll long long #define LL long long #define ld long double #define endl \n #defi…