首页 > 其他分享 >3.CF343D Water Tree 树剖+线段树区间覆盖

3.CF343D Water Tree 树剖+线段树区间覆盖

时间:2022-10-28 10:35:04浏览次数:79  
标签:rt lazy return 树剖 int CF343D Tree mid define


3.CF343D Water Tree 树剖+线段树区间覆盖


线段树维护树上覆盖问题,树剖序列化维护序列覆盖。

洛谷传送门:​​CF343D Water Tree - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)​

CF传送门:​​D. Water Tree (codeforces.com)​

题目分析

给出一棵以 为根节点的 个节点的有根树。每个点有一个权值,初始为

  • 次操作。操作有种:
  1. 将点和其子树上的所有节点的权值改为
  2. 将点的路径上的所有节点的权值改为
  3. 询问点

树上问题序列化,树剖一下,线段树维护区间推平操作

  1. 对应线段树区间:
  2. 对应线段树区间:沿重链向上跳到根节点,至多log个区间,第一个区间:
  3. 直接树上单点查询即可

Code

#include <bits/stdc++.h>
#pragma gcc optimize("O2")
#pragma g++ optimize("O2")
#define int long long
#define endl '\n'
using namespace std;

const int N = 2e5 + 10, MOD = 1e9 + 7;

vector<int> g[N];
int a[N];

int pfa[N], dep[N], siz[N], son[N], top[N], dfn[N], rnk[N], ind;

void dfs1(int u, int fa){
pfa[u] = fa, dep[u] = dep[fa] + 1, siz[u] = 1;
for(auto &v : g[u]){
if(v == fa) continue;
dfs1(v, u);
siz[u] += siz[v];
if(siz[v] > siz[son[u]]) son[u] = v;
}
}

void dfs2(int u, int tp){
dfn[u] = ++ind, rnk[ind] = u, top[u] = tp;
if(!son[u]) return;
dfs2(son[u], tp);
for(auto & v: g[u]){
if(v == pfa[u] || v == son[u]) continue;
dfs2(v, v);
}
}


namespace SegTree{
#define ls rt << 1
#define rs rt << 1 | 1
#define lson ls, l,
#define rson rs, mid + 1,

int tree[N << 2], lazy[N << 2];

inline void push_down(int rt, int ll, int lr, int rl, int rr){
if(!lazy[rt]) return;
if(ll == lr) tree[ls] += (dep[rnk[ll]] & 1 ? 1 : -1) * lazy[rt];
if(rl == rr) tree[rs] += (dep[rnk[rr]] & 1 ? 1 : -1) * lazy[rt];
lazy[ls] += lazy[rt], lazy[rs] += lazy[rt];
lazy[rt] = 0;
}

void build(int rt, int l, int r){
lazy[rt] = 0;
if(l == r){
tree[rt] = a[rnk[l]];
return;
}
int mid = l + r >> 1;
build(lson), build(rson);
}

void update(int rt, int l, int r, int L, int R, int val){
if(l >= L && r <= R){
if(l == r) tree[rt] += (dep[rnk[l]] & 1 ? 1 : -1) * val;
else lazy[rt] += val;
return;
}
int mid = l + r >> 1;
push_down(rt, l, mid, mid + 1, r);
if(mid >= L) update(lson, L, R, val);
if(mid < R) update(rson, L, R, val);
}

int query(int rt, int l, int r, int pos){
if(l == r) return tree[rt];
int mid = l + r >> 1;
push_down(rt, l, mid, mid + 1, r);
if(mid >= pos) return query(lson, pos);
else return query(rson, pos);
}
}

#define SEGRG 1, 1,

inline void solve(){
int n, m = 0; cin >> n >> m;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n - 1; i++){
int u = 0, v = 0; cin >> u >> v;
g[u].emplace_back(v);
g[v].emplace_back(u);
}
dfs1(1, 0), dfs2(1, 1);
SegTree::build(1, 1, n);
while(m--){
int op, v; cin >> op >> v;
if(op == 1){
int x = 0; cin >> x;
if(!(dep[v] & 1)) x *= -1;
SegTree::update(SEGRG, dfn[v], dfn[v] + siz[v] - 1, x);
} else {
cout << SegTree::query(SEGRG, dfn[v]) << endl;
}
}

}

signed main(){
ios_base::sync_with_stdio(false), cin.tie(0);
cout << fixed << setprecision(12);
int t = 1; //cin >> t;
while(t--) solve();
return 0;
}


标签:rt,lazy,return,树剖,int,CF343D,Tree,mid,define
From: https://blog.51cto.com/u_12372287/5803551

相关文章

  • 9.CF490F Treeland Tour 线段树合并
    9.CF490FTreelandTour线段树合并给出一棵带点权树,求树上最长上升子序列的长度对每个点开两棵线段树,记录叶节点到当前节点的LIS和LDS,然后合并时取最大值即可洛谷传送门:​......
  • Nauuo and Binary Tree 题解
    linkSolution超级有意思的题目,可惜还是做不出来。/kk我们首先看出我们可以求出每一个点的深度。然后考虑深度从小到大考虑对于每一个点找出它的父亲。你发现如果求出两......
  • [repo] error.GitError: cannot initialize work tree && contains uncommitted chang
    备忘一下error.GitError:cannotinitializeworktree.repo/repo/repo--tracesync-cdfjuwan@juwan-n85-dls:/media/juwan/70970A1D041A95C2/rk3399_linux_relea......
  • mysqlb+tree结构
    怎样在MySQL表中存储树形结构数据很高兴为您解答。一般比较普遍的就是四种方法:(具体见SQLAnti-patterns这本书)AdjacencyList:每一条记录存parent_idPathEnumerations:每一......
  • Git worktree(工作树)
    worktree工作树简介重新给分支/提交一个新的工作区域,且原工作区无法在switch到那个分支,只有释放了才行新增一个工作树之后,原仓库目录的.git文件夹中产生一个worktree......
  • [Oracle] LeetCode 314 Binary Tree Vertical Order Traversal
    Giventherootofabinarytree,returntheverticalordertraversalofitsnodes'values.(i.e.,fromtoptobottom,columnbycolumn).Iftwonodesareinth......
  • 2022 年上海市大学生程序设计竞赛 - 十月赛 B. Questions on Binary Tree
    给定一棵n个节点的完全二叉树以及m次询问,每次询问需要计算给定节点在先序遍历的顺序。思路就是从给定的节点不断向上跳,如果当前节点是左儿子则给答案+1,是右儿子则给答案+1......
  • CF1092F Tree with Maximum Cost
    题目链接:​​传送门​​是​​这个题​​​的一个变形就是最小值改成最大值懒了直接改了改当时的代码当时的题解里也有解析#include<iostream>#include<cstdio>#inclu......
  • CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
    CF741DArpa’sletter-markedtreeandMehrdad’sDokhtar-koshpaths给定一颗以\(1\)为根的树每个节点上有一个\(a\simv\)的小写字母,求每个子树内最长的链的长度......
  • web技术分享| 虚拟 tree
    查了好久,觉得使用AntDesignVue中的Tree树形控件因项目需求,节点的移动不通过拖拽移动,需要通过弹窗实现节点的移动,因此基于添加、删除实现。当前仅使用节点添加、删除......