洛谷【P3833】树链剖分线段树区间操作

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
const int maxm = maxn << 1;
///图(链式前向星出了点问题)
vector<int> g[maxm];
///线段树
struct node{
    int l, r, len;
    ll sum, lazy;
    int mid(){
        return (l + r) >> 1;
    }
}tree[maxn << 2];
///全局变量
int fa[maxn], dep[maxn], siz[maxn], son[maxn];///dfs1
int tim, dfn[maxn], top[maxn], w[maxn], val[maxn];///dfs2


void dfs1(int u, int f){
    fa[u] = f;
    dep[u] = dep[f] + 1;
    siz[u] = 1;
    int maxsize = -1;
    for(int i = 0; i < g[u].size(); i++){
        int v = g[u][i];
        if(v == f) continue;
        dfs1(v, u);
        siz[u] += siz[v];
        if(siz[v] > maxsize){
            maxsize = siz[v];
            son[u] = v;
        }
    }
}

void dfs2(int u, int t){
    dfn[u] = ++tim;
    top[u] = t;
    w[tim] = u;
    if(!son[u]) return;
    dfs2(son[u], t);
    for(int i = 0; i < g[u].size(); i++){
        int v = g[u][i];
        if(v == fa[u] || v == son[u]) continue;
        dfs2(v, v);
    }
}

inline void PushDown(int root){
    if(tree[root].lazy){
        tree[root << 1].lazy += tree[root].lazy;
        tree[root << 1 | 1].lazy += tree[root].lazy;
        tree[root << 1].sum += tree[root].lazy * tree[root << 1].len;
        tree[root << 1 | 1].sum += tree[root].lazy * tree[root << 1 | 1].len;
        tree[root].lazy = 0;
    }
}

inline void PushUp(int root){
    tree[root].sum = tree[root << 1].sum + tree[root << 1 | 1].sum;
}

void Build(int root, int l, int r){
    tree[root].len = r - l + 1;
    tree[root].lazy = 0;
    tree[root].sum = 0;
    tree[root].l = l;
    tree[root].r = r;
    if(l == r){
        tree[root].sum = val[w[l]];
        return;
    }
    int mid = tree[root].mid();
    Build(root << 1, l, mid);
    Build(root << 1 | 1, mid + 1, r);
    PushUp(root);
}

void UpDate(int root, int l, int r, int c){
    if(tree[root].l >= l && r >= tree[root].r){
        tree[root].lazy += c;
        tree[root].sum += c * tree[root].len;
        return;
    }
    if(tree[root].l == tree[root].r) return;
    PushDown(root);
    int mid = tree[root].mid();
    if(r <= mid) UpDate(root << 1, l, r, c);
    else if(l > mid) UpDate(root << 1 | 1, l, r, c);
    else{
        UpDate(root << 1, l, mid, c);
        UpDate(root << 1 | 1, mid + 1, r, c);
    }
    PushUp(root);
}

ll Query(int root, int l, int r){
    if(tree[root].l >= l && r >= tree[root].r) return tree[root].sum;
    PushDown(root);
    int mid = tree[root].mid();
    if(r <= mid) return Query(root << 1, l, r);
    else if(l > mid) return Query(root << 1 | 1, l, r);
    else return Query(root << 1, l, mid) + Query(root << 1 | 1, mid + 1, r);
}

inline void mson(int x, int z){
    UpDate(1, dfn[x], dfn[x] + siz[x] - 1, z);
}

inline ll qson(int x){
    return Query(1, dfn[x], dfn[x] + siz[x] - 1);
}

inline void ChangeLink(int x, int y, int z){
    while(top[x] != top[y]){
        if(dep[top[x]] < dep[top[y]]) swap(x, y);
        UpDate(1, dfn[top[x]], dfn[x], z);
        x = fa[top[x]];
    }
    if(dep[x] > dep[y]) swap(x, y);
    UpDate(1, dfn[x], dfn[y], z);
}

inline ll QueryLink(int x, int y){
    ll res = 0;
    while(top[x] != top[y]){
        if(dep[top[x]] < dep[top[y]]) swap(x, y);
        res += Query(1, dfn[top[x]], dfn[x]);
        x = fa[top[x]];
    }
    if(dep[x] > dep[y]) swap(x, y);
    res += Query(1, dfn[x], dfn[y]);
    return res;
}

int main(){
    int n, u, v, x, y, z, m;
    char s[10];
    scanf("%d", &n);
    for(int i = 1; i < n; i++){
        scanf("%d%d", &u, &v);
        g[u + 1].push_back(v + 1);
        g[v + 1].push_back(u + 1);
    }
    dfs1(1, 0);
    dfs2(1, 1);
    Build(1, 1, tim);
    scanf("%d", &m);
    getchar();
    for(int i = 1; i <= m; i++){
        scanf("%s", s);
        if(s[0] == 'A'){
            scanf("%d%d%d", &x, &y, &z);
            ChangeLink(x + 1, y + 1, z);
        }
        else{
            scanf("%d", &x);
            printf("%lld\n", qson(x + 1));
        }
    }

    return 0;
}

全部评论

相关推荐

03-06 20:09
贵州大学 Java
King987:你这个学历找个中大厂刷实习经历都是可以的,但是项目要有亮点才行,这个什么外卖就不要做了,去找找最新的项目,至少涉及高并发或者是新型的AI技术mcp rag啥的 ,我在出简历点评,但是你这个没什么好点评的,内容太少,而且含金量太低。自己改一改吧,或者看一下我的项目地址中,那里有大厂最近做过的实习项目
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
正在热议
更多
# 春招至今,你的战绩如何? #
10999次浏览 94人参与
# 你的实习产出是真实的还是包装的? #
1943次浏览 42人参与
# MiniMax求职进展汇总 #
24114次浏览 309人参与
# 军工所铁饭碗 vs 互联网高薪资,你会选谁 #
7628次浏览 43人参与
# 简历第一个项目做什么 #
31736次浏览 339人参与
# 重来一次,我还会选择这个专业吗 #
433536次浏览 3926人参与
# 巨人网络春招 #
11361次浏览 223人参与
# 当下环境,你会继续卷互联网,还是看其他行业机会 #
187191次浏览 1122人参与
# 牛客AI文生图 #
21445次浏览 238人参与
# 不考虑薪资和职业,你最想做什么工作呢? #
152441次浏览 888人参与
# 研究所笔面经互助 #
118960次浏览 577人参与
# 简历中的项目经历要怎么写? #
310349次浏览 4217人参与
# AI时代,哪些岗位最容易被淘汰 #
63803次浏览 826人参与
# 面试紧张时你会有什么表现? #
30509次浏览 188人参与
# 你今年的平均薪资是多少? #
213128次浏览 1039人参与
# 你怎么看待AI面试 #
180122次浏览 1258人参与
# 高学历就一定能找到好工作吗? #
64331次浏览 620人参与
# 你最满意的offer薪资是哪家公司? #
76537次浏览 374人参与
# 我的求职精神状态 #
448121次浏览 3129人参与
# 正在春招的你,也参与了去年秋招吗? #
363503次浏览 2638人参与
# 腾讯音乐求职进展汇总 #
160672次浏览 1112人参与
# 校招笔试 #
471140次浏览 2964人参与
牛客网
牛客网在线编程
牛客网题解
牛客企业服务