P3128 [USACO15DEC]Max Flow P(树上倍增和树链剖分)
思路1(树上倍增$ + $树上差分)
每次都修改一条从\(u\)到\(v\),不就是树上差分的专门操作吗??
直接用倍增求\(LCA\),每次\(d[u]++,d[v]++,d[LCA(u,v)]--,d[f[LCA(u,v)][0]]--\)。
最后记得算下前缀和。
代码1
#include <iostream>
#include <cstring>
using namespace std;
const int N = 50010,M = 2 * N,MAX_LOG = 20;
int n,m;
int h[N],e[M],ne[M],idx;
int w[N];
int dep[N];
int f[N][MAX_LOG];
void add (int a,int b) {
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
void dfs1 (int u,int fa) {
f[u][0] = fa;
for (int i = 1;i <= MAX_LOG - 1;i++) f[u][i] = f[f[u][i - 1]][i - 1];
for (int i = h[u];~i;i = ne[i]) {
int j = e[i];
if (j == fa) continue;
dep[j] = dep[u] + 1;
dfs1 (j,u);
}
}
int get_LCA (int a,int b) {
if (dep[a] < dep[b]) swap (a,b);
for (int i = MAX_LOG - 1;i >= 0;i--) {
if (dep[f[a][i]] >= dep[b]) a = f[a][i];
}
if (a == b) return a;
for (int i = MAX_LOG - 1;i >= 0;i--) {
if (f[a][i] != f[b][i]) a = f[a][i],b = f[b][i];
}
return f[a][0];
}
int dfs2 (int u,int fa) {
int ans = 0;
for (int i = h[u];~i;i = ne[i]) {
int j = e[i];
if (j == fa) continue;
ans = max (ans,dfs2 (j,u));
w[u] += w[j];
}
return max (ans,w[u]);
}
int main () {
memset (h,-1,sizeof (h));
cin >> n >> m;
for (int i = 1;i <= n - 1;i++) {
int a,b;
cin >> a >> b;
add (a,b),add (b,a);
}
dfs1 (1,0);
while (m--) {
int a,b;
cin >> a >> b;
int anc = get_LCA (a,b);
w[a]++,w[b]++,w[anc]--,w[f[anc][0]]--;
}
cout << dfs2 (1,0) << endl;
return 0;
}
思路2(树链剖分)
修改一条\(u\)到\(v\)的路径,查询整棵树的最大值,不就是树剖的模板吗??
直接套模板(懒得讲
代码2
#include <iostream>
#include <cstring>
using namespace std;
const int N = 50010,M = 2 * N,MAX_LOG = 20;
int n,m;
int h[N],e[M],ne[M],idx;
int timestamp;
int dep[N],s[N],son[N],fa[N];
int id[N],top[N];
struct segment_tree_node {
int l,r;
int maxx,add;
}tr[4 * N];
void add (int a,int b) {
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
void push_up (int u) {
tr[u].maxx = max (tr[u << 1].maxx,tr[u << 1 | 1].maxx);
}
void push_down (int u) {
auto &root = tr[u],&left = tr[u << 1],&right = tr[u << 1 | 1];
if (root.add) {
left.maxx += root.add,left.add += root.add;
right.maxx += root.add,right.add += root.add;
root.add = 0;
}
}
void build_segment_tree (int u,int l,int r) {
if (l == r) {
tr[u] = {l,r,0,0};
return ;
}
tr[u] = {l,r};
int mid = l + r >> 1;
build_segment_tree (u << 1,l,mid),build_segment_tree (u << 1 | 1,mid + 1,r);
push_up (u);
}
void modify (int u,int l,int r,int d) {
if (l <= tr[u].l && tr[u].r <= r) {
tr[u].add += d,tr[u].maxx += d;
return ;
}
push_down (u);
int mid = tr[u].l + tr[u].r >> 1;
if (l <= mid) modify (u << 1,l,r,d);
if (r >= mid + 1) modify (u << 1 | 1,l,r,d);
push_up (u);
}
int query_max (int u,int l,int r) {
if (l <= tr[u].l && tr[u].r <= r) return tr[u].maxx;
push_down (u);
int mid = l + r >> 1;
int ans = 0;
if (l <= mid) ans = max (ans,query_max (u << 1,l,r));
if (r >= mid + 1) ans = max (ans,query_max (u << 1 | 1,l,r));
return ans;
}
void dfs1 (int u,int f) {
dep[u] = dep[f] + 1,s[u] = 1,fa[u] = f;
for (int i = h[u];~i;i = ne[i]) {
int j = e[i];
if (j == f) continue;
dfs1 (j,u);
s[u] += s[j];
if (s[j] > s[son[u]]) son[u] = j;
}
}
void dfs2 (int u,int top_node) {
id[u] = ++timestamp,top[u] = top_node;
if (!son[u]) return ;
dfs2 (son[u],top_node);
for (int i = h[u];~i;i = ne[i]) {
int j = e[i];
if (j == fa[u] || j == son[u]) continue;
dfs2 (j,j);
}
}
void modify_path (int a,int b) {
while (top[a] != top[b]) {
if (dep[top[a]] < dep[top[b]]) swap (a,b);
modify (1,id[top[a]],id[a],1);
a = fa[top[a]];
}
if (dep[a] > dep[b]) swap (a,b);
modify (1,id[a],id[b],1);
}
int query_subtree (int u) {
return query_max (1,id[u],id[u] + s[u] - 1);
}
int main () {
memset (h,-1,sizeof (h));
cin >> n >> m;
for (int i = 1;i <= n - 1;i++) {
int a,b;
cin >> a >> b;
add (a,b),add (b,a);
}
build_segment_tree (1,1,n),dfs1 (1,0),dfs2 (1,1);
while (m--) {
int a,b;
cin >> a >> b;
modify_path (a,b);
}
cout << query_subtree (1) << endl;
return 0;
}
P3128 [USACO15DEC]Max Flow P(树上倍增和树链剖分)的更多相关文章
- [luogu P3128][USACO15DEC]Max Flow [LCA][树上差分]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
- 【HAOI2015】树上操作(树链剖分)
题面 Description 有一棵点数为N的树,以点1为根,且树点有边权.然后有M个操作,分为三种: 操作1:把某个节点x的点权增加a. 操作2:把某个节点x为根的子树中所有点的点权都增加a. 操作 ...
- 洛谷P3178 树上操作 [HAOI2015] 树链剖分
正解:树链剖分+线段树 解题报告: 传送门! 树链剖分+线段树算是基操了趴,,, 就无脑码码码,没有任何含金量,不需要动脑子,然后码量其实也不大,就很爽 比树剖的板子还要板子一些hhhhh 放下代码就 ...
- [HAOI2015]树上操作(树链剖分)
[HAOI2015]树上操作(luogu) Description 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增 ...
- BZOJ_4034 [HAOI2015]树上操作 【树链剖分dfs序+线段树】
一 题目 [HAOI2015]树上操作 二 分析 树链剖分的题,这里主要用到了$dfs$序,这题比较简单的就是不用求$lca$. 1.和树链剖分一样,先用邻接链表建双向图. 2.跑两遍$dfs$,其实 ...
- 模板 树上求LCA 倍增和树链剖分
//233 模板 LCA void dfs(int x,int f){ for(int i=0;i<E[x].size();i++){ int v = E[x][i]; if(v==f)cont ...
- 「HAOI2015」「LuoguP3178」树上操作(树链剖分
题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增 ...
- 洛谷P4689 [Ynoi2016]这是我自己的发明(树上莫队+树链剖分)
题目描述 您正在打galgame,然后突然家长进来了,于是您假装在写数据结构题: 给一个树,n 个点,有点权,初始根是 1. m 个操作,每次操作: 1.将树根换为 x. 2.给出两个点 x,y,从 ...
- 4034. [HAOI2015]树上操作【树链剖分】
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...
- [HAOI2015]树上操作(树链剖分,线段树)
题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 ...
随机推荐
- 2020ICPC沈阳I - Rise of Shadows
剩余系 Problem - I - Codeforces 题意 给定 \(H,M,A\) \(2<=H,M<=10^9,\;0<=A<=\frac {H*M}2\) 假设一个钟 ...
- 什么是bootstrap?
In computing, the term bootstrap means to boot or to load a program into a computer using a much sma ...
- PPT模板网址
PPT免费下载网址: https://www.1ppt.com/ PPT模板下载:www.1ppt.com/moban/ 行业PPT模板:www.1ppt.com/han ...
- 有一个按钮,点击后就发起一次请求,我现在要限制每2S只能发起一次请求,怎么办?
1.防抖/节流方案2.临时变量记录最后发起请求的时间,点击时对比时间差的方案
- [BOM]实现页面loading效果,在图片资源加载完之前显示loading
使用到jquery. 判断整个页面是否加载完: // 这是根据js判断,页面加载完毕就显示 window.onload = function () { // console.log('load com ...
- 【Java】时间类型
Date 转 timeStamp long time = System.currentTimeMillis(); // 秒级 long time = System.currentTimeMillis( ...
- python中,元组,列表,字典,字符串的相互转换
#author:RXS002 #1.字典 dict = {'name':'Zara','age':7,'class':'First'} #字典转换为字符串,返回:<type 'str'> ...
- React-Native笔记--node_modules删除
在开发RN项目过程中,经常会用到删除node_modules文件夹的命令,现总结如下: 方式1: npm install rimraf -g rimraf node_modules方式2: rmdir ...
- vue后台管理系统——项目优化上线
1. 项目优化 项目优化策略: 使用进度条nprogress 生成打包报告 第三方库启用 CDN Element-UI 组件按需加载 路由懒加载 首页内容定制 ① 使用进度条nprogress 在页面 ...
- CSS选择符及盒模型
一.选择符 1.类型选择符(标签选择符) 特点:能选中当前结构里面(全部同名)标签. 应用:统一某一标签样式时或清除某一标签默认样式时. 2.id选择符 特点:(唯一性!)在同一个页面里面,一个id名 ...