首页 > 其他分享 >动态树 树剖

动态树 树剖

时间:2023-01-01 12:22:20浏览次数:22  
标签:树剖 int siz top dfs son dep 动态

//题意:有一棵树,有两个指令
//      指令1:0 u delta,这棵树长出了一些果子, 即u的子树中的每个节点都会长出delta个果子
//        指令2:1 k u1 v1 ... uk vk,小明希望你求出几条树枝上的果子数. 一条树枝其实就是一个从某个节点到根的路径的一段. 每次小明会选定一些树枝, 让你求出在这些树枝
//        上的节点的果子数的和。注意, 树枝之间可能会重合, 这时重合的部分的节点的果子只要算一次。
//思路:第一个指令很简单,直接dfs序区间操作就好
//      主要是第二个指令,充分发挥了树剖将路径操作转化为区间的性质
//      将路径转化许多区间之后,如果有路径重合,那么就是有区间重合,我们直接并区间就好
//      (ps:本题的查询部分的树状数组懒得写了,只写到区间并的阶段)
//
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10;
int tr[N];
int n, q;
vector<int> mp[N];
int dep[N], siz[N], son[N], L[N], R[N], f[N], tot, top[N], idx[N];
void dfs(int x, int fa) {
    dep[x] = dep[fa] + 1;
    f[x] = fa;
    siz[x] = 1;
    for (auto y : mp[x]) {
        if (y == fa) continue;
        dfs(y, x);
        siz[x] += siz[y];
        if (siz[son[x]] < siz[y])
            son[x] = y;
    }
}//重链剖分前置处理
void dfs1(int x, int w) {
    L[x] = ++tot;
    top[x] = w;
    idx[tot] = x;
    if (son[x]) dfs1(son[x], w);
    for (auto y : mp[x]) {
        if (y == f[x] || y == son[x]) continue;
        dfs1(y, y);
    }
    R[x] = tot;
}//重链剖分,注意dfs序是这个时候的dfs序,因为之后要根据这个来更新线段树的(这道题用树状数组来整)
void modify(int x, int s) {
    for (; x <= n; x += x & (-x))
        tr[x] += s;
}
pair<int, int> edge[4 * N]; int cnt;
void query(int u, int v) {
    while(top[u]!=top[v]){
        if (dep[top[u]] < dep[top[v]]) {
            edge[++cnt] = { L[top[v]], L[v] };
            v = f[top[v]];
        }
        else {
            edge[++cnt] = { L[top[u]], L[u] };
            u = f[top[u]];
        }
    }
    if (dep[u] <= dep[v]) edge[++cnt] = { L[u],L[v] };
    else edge[++cnt] = { L[v],L[u] };
}
int way[4 * N][2]; int cnt1;//记录最终路径数
void merge() {
    sort(edge + 1, edge + 1 + cnt);
    way[0][0] = 0, way[0][1] = 0;
    for (int i = 1; i <= cnt; i++) {
        if (edge[i].first <= way[cnt1][1])
            way[cnt1][1] = max(way[cnt1][1], edge[i].second);
        else if (edge[i].first > way[cnt1][1]) {
            way[++cnt1][0] = edge[i].first;
            way[cnt1][1] = edge[i].second;
        }
    }
}//合并所有询问区间
int lookfor(int x) {
    int s = 0;
    for (; x; x -= x & (-x))
        s += tr[x];
    return s;
}
int query1() {
    int ans = 0;
    for (int i = 1; i <= cnt1; i++) {
        ans = ans - lookfor(way[i][0]);
        ans = ans + lookfor(way[i][1]);
        //cout << way[i][0] << " " << way[i][1] << endl;
    }
    return ans;
}
signed main() {
    cin >> n;
    for (int i = 1; i <= n - 1; i++) {
        int a, b; cin >> a >> b;
        mp[a].push_back(b);
        mp[b].push_back(a);
    }
    dep[0] = 0;
    dfs(1, 0);
    dfs1(1, 1);
    cin >> q;
    for (int i = 1; i <= q; i++) {
        int od, a, b, c; cin >> od;
        if (od == 0) {
            cin >> a >> b;
            //modify(R[a], b);
            //modify(L[a], -b);
        }
        else {
            cin >> c;
            for (int j = 1; j <= c; j++) {
                cin >> a >> b;
                query(a, b);
            }
            merge();
            int ans = 0;
            ans = ans + query1();
            //for (int i = 1; i <= cnt; i++)
                //cout << edge[i].first << " " << edge[i].second << endl;
            cout << ans << endl;
        }
    }
    return 0;
}

 

标签:树剖,int,siz,top,dfs,son,dep,动态
From: https://www.cnblogs.com/Aacaod/p/17017941.html

相关文章

  • 动态代理
    动态代理1.什么是代理模式代理模式是一种设计模式,就是通过代理对象操作原对象并且给原对象添加一些额外功能。代理模式分为静态代理和动态代理两种2.静态代理静态代......
  • [leetcode]第 10 天 动态规划(中等)
    46.把数字翻译成字符串思路每个数字都有两种翻译情况,一种是和前一位数字一起被翻译,一种是单独被翻译。状态定义:dp[i]表示以xi结尾的数字的翻译方案数量;状态转移方程:f......
  • [leetcode]第 9 天 动态规划(中等)
    42.连续子数组的最大和思路状态定义:dp[i]表示以nums[i]结尾的连续子数组的最大和;状态转移方程:dp[i-1]>0,dp[i]=dp[i-1]+nums[i];dp[i-1]<=0,dp[i]=num......
  • SpringBoot动态更新yml文件
    前言在系统运行过程中,可能由于一些配置项的简单变动需要重新打包启停项目,这对于在运行中的项目会造成数据丢失,客户操作无响应等情况发生,针对这类情况对开发框架进行升级提......
  • Allure08-动态用例优先级与链接
    动态用例优先级allure.dynamic.severity(用例优先级)可以使用参数化的参数只能放到函数和方法中对于一个子功能或测试需求的每一条用例,都可以有自己的severity写法......
  • Allure06-动态测试集与功能特性
    动态测试集特性allure.dynamic.suite('某用例所属的测试集名称')动态特性放到函数或方法中不建议使用allure.dynamic.suite,否则会导致测试集名称显示混乱:既包含模块名......
  • Allure07-动态用例标题、用例描述和测试步骤
    动态用例标题allure.dynamic.title('动态用例标题')必须放在函数、方法之内可以使用参数化的参数每条用例执行一次会覆盖@allure.title动态用例描述allure.dy......
  • SpringBoot动态更新yml文件
    前言在系统运行过程中,可能由于一些配置项的简单变动需要重新打包启停项目,这对于在运行中的项目会造成数据丢失,客户操作无响应等情况发生,针对这类情况对开发框架进行升级提......
  • HZOJ 切割回文 动态规划
    题面: 解题思路:本题是一个经典的动态规划的题目。定义动态规划数组dp,dp[i]的含义是子串str[0…i]至少需要切割几次,才能把str[0…i]全部切成回文子串。那么dp[len-1]......
  • 2022最炫酷的圣诞树合集(附动态效果展示和网盘源码)
    文章目录​​3D旋转水晶球(雪屋)​​​​3D旋转水晶球(圣诞树)​​​​豪华圣诞树​​​​Garland圣诞树​​​​花灯圣诞树​​​​Live圣诞树​​​​五彩圣诞树​​​​Gre......