此类型题目有两种比较常见的做法:树链剖分和树上差分。

本题有多组修改一组询问,因此树上差分会比树链剖分优秀很多。

这里两种方法都进行介绍。


树链剖分和树上差分的本质都是将一颗树转换为一个区间,然后进行操作。

也就是说,先将一颗树变成区间,然后套用线段树/树状数组和差分。


树链剖分的具体流程不多加叙述,可以自己去翻它的模板题。

本题维护区间修改单点查询就OK了,最后输出答案的时候直接遍历所有节点取最大值。

1956ms,9805kb

#include<iostream>
#include<cstdio>
#include<algorithm>
#define qwq int
#define re register
using namespace std;
namespace Solve{
#define N 200200
qwq n,m;
qwq cnt;
qwq head[N];
struct node{
qwq to,next;
}edge[N<<1];
inline void add(qwq a,qwq b){
edge[++cnt].to=b,edge[cnt].next=head[a],head[a]=cnt;
}
qwq dfn;
qwq dep[N],fa[N],size[N],son[N],top[N],id[N];
inline void dfs1(qwq now,qwq father,qwq deep){
dep[now]=deep,fa[now]=father,size[now]=1;qwq max_son=-1;
for(re qwq i=head[now];i;i=edge[i].next){
qwq to=edge[i].to;
if(to==father)continue;
dfs1(to,now,deep+1);
size[now]+=size[to];
if(size[to]>max_son)max_son=size[to],son[now]=to;
}
}
inline void dfs2(qwq now,qwq topf){
id[now]=++dfn,top[now]=topf;
if(!son[now])return;
dfs2(son[now],topf);
for(re qwq i=head[now];i;i=edge[i].next){
qwq to=edge[i].to;
if(to==son[now]||to==fa[now])continue;
dfs2(to,to);
}
}
struct tnode{
qwq l,r,val,tag;
}tree[N<<2];
inline void pushup(qwq pos){
tree[pos].val=tree[pos<<1].val+tree[pos<<1|1].val;
}
inline void pushdown(qwq pos){
if(tree[pos].tag){
tree[pos<<1].tag+=tree[pos].tag,tree[pos<<1|1].tag+=tree[pos].tag;
tree[pos<<1].val+=tree[pos].tag*(tree[pos<<1].r-tree[pos<<1].l+1);
tree[pos<<1|1].val+=tree[pos].tag*(tree[pos<<1|1].r-tree[pos<<1|1].l+1);
tree[pos].tag=0;
}
}
inline void build(qwq l,qwq r,qwq pos){
tree[pos].l=l,tree[pos].r=r;
if(l==r){
tree[pos].val=0;
return;
}
qwq mid=(l+r)>>1;
build(l,mid,pos<<1),build(mid+1,r,pos<<1|1);
pushup(pos);
}
inline void update(qwq l,qwq r,qwq v,qwq pos){
if(l<=tree[pos].l&&tree[pos].r<=r){
tree[pos].val+=v*(tree[pos].r-tree[pos].l+1);
tree[pos].tag+=v;
return;
}
pushdown(pos);
qwq mid=(tree[pos].l+tree[pos].r)>>1;
if(l<=mid)update(l,r,v,pos<<1);
if(mid<r)update(l,r,v,pos<<1|1);
pushup(pos);
}
inline qwq query(qwq l,qwq r,qwq pos){
if(l<=tree[pos].l&&tree[pos].r<=r){
return tree[pos].val;
}
pushdown(pos);
qwq mid=(tree[pos].l+tree[pos].r)>>1,ans=0;
if(l<=mid)ans=max(ans,query(l,r,pos<<1));
if(mid<r)ans=max(ans,query(l,r,pos<<1|1));
return ans;
}
inline qwq queryRange(qwq x,qwq y){
qwq ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
ans=max(ans,query(id[top[x]],id[x],1));
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
ans=max(ans,query(id[x],id[y],1));
return ans;
}
inline void updateRange(qwq x,qwq y,qwq v){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
update(id[top[x]],id[x],v,1);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
update(id[x],id[y],v,1);
}
inline void solve(){
scanf("%d%d",&n,&m);
for(re qwq i=1;i<=n-1;++i){
qwq x,y;
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
dfs1(1,1,1);
dfs2(1,1);
build(1,n,1);
while(m--){
qwq x,y;
scanf("%d%d",&x,&y);
updateRange(x,y,1);
}
qwq ans=0;
for(re qwq i=1;i<=n;++i)ans=max(ans,query(id[i],id[i],1));
cout<<ans;
}
}
using namespace Solve;
qwq main(){
solve();
}

很明显,树链剖分码量比较高,在赛场上码力不足的选手容易陷入调试的巨坑,因此还是首推码量小并且(对于本题而言)速度快的树上差分。

需注意的是:树上差分适用于多组修改单组询问的题目,其他情况会T上天。

对于要更新的两个点而言,我们只要在他们上面各标记+1,然后在他们的lca和lca的父亲上各标记-1即可。

然后在询问的时候跑一下dfs统计一下就出答案了。

(lca用倍增,当然tarjan树剖都行,反正别裸的直接套上去)

懒得打代码了。光速逃

题解 P3128 【[USACO15DEC]最大流Max Flow】的更多相关文章

  1. 洛谷P3128 [USACO15DEC]最大流Max Flow

    P3128 [USACO15DEC]最大流Max Flow 题目描述 Farmer John has installed a new system of N-1N−1 pipes to transpo ...

  2. P3128 [USACO15DEC]最大流Max Flow(LCA+树上差分)

    P3128 [USACO15DEC]最大流Max Flow 题目描述 Farmer John has installed a new system of  pipes to transport mil ...

  3. 洛谷P3128 [USACO15DEC]最大流Max Flow [树链剖分]

    题目描述 Farmer John has installed a new system of  pipes to transport milk between the  stalls in his b ...

  4. 【luogu P3128 [USACO15DEC]最大流Max Flow】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3128 菜 #include <cstdio> #include <cstring> ...

  5. 题解——洛谷P3128 [USACO15DEC]最大流Max Flow

    裸的树上差分 因为要求点权所以在点上差分即可 #include <cstdio> #include <algorithm> #include <cstring> u ...

  6. 洛谷 P3128 [ USACO15DEC ] 最大流Max Flow —— 树上差分

    题目:https://www.luogu.org/problemnew/show/P3128 倍增求 lca 也写错了活该第一次惨WA. 代码如下: #include<iostream> ...

  7. 洛谷P3128 [USACO15DEC]最大流Max Flow [倍增LCA]

    题目描述 Farmer John has installed a new system of  pipes to transport milk between the  stalls in his b ...

  8. luogu P3128 [USACO15DEC]最大流Max Flow (树上差分)

    题目描述 Farmer John has installed a new system of N-1N−1 pipes to transport milk between the NN stalls ...

  9. 树上差分——点差分裸题 P3128 [USACO15DEC]最大流Max Flow

    讲解: https://rpdreamer.blog.luogu.org/ci-fen-and-shu-shang-ci-fen #include <bits/stdc++.h> #def ...

  10. P3128 [USACO15DEC]最大流Max Flow

    思路 这个题哪里有那么费脑筋 我们可以树链剖分嘛LCT昨天学的时候睡着了,不是太会 两遍dfs+一个5行的BIT 其实树链剖分学好了对倍增和LCT理解上都有好处 一条路径上的修改 由于一条剖出来的链是 ...

随机推荐

  1. Java web课程学习之会话(Session)

    Session会话   l web应用中的会话是指一个客户端浏览器与web服务器之间连续发生一系列请求和响应过程 l web应用的会话状态是指web服务器与浏览器在会话过程中产生的状态信息,借助会话状 ...

  2. [CTSC1999][网络流24题]家园

    题目:洛谷P2754. 题目大意:有$n$个空间站,$m$个飞船,每个飞船有各自的停靠站点,并且从第一个停靠站点开始,不断循环.每个飞船有不同的容量(-1为月球,0为地球).每个飞船初始停在第一个停靠 ...

  3. 循环语句第2种 WHILE ... LOOP END LOOP;

     --------第2种--------   WHILE ... LOOP   END LOOP;    declare    n number(3) :=1;  begin    WHILE n&l ...

  4. 洛谷 2409 dp 月赛题目

    洛谷 2409 dp 洛谷十月月赛T1,一道有些interesting的dp题目,当时做的时候想的比较复杂,根本没有往dp的方向去想.. 非官方题解: 1.据说可以使用优先队列来处理,参见Uva119 ...

  5. Docker 管理工具的选择:Kubernetes 还是 Swarm?

    [编者的话]选择Kubernetes 或者 Swarm 就像在将 Linux 桌面发行版的范围缩小到两个后选出一个最喜欢的.哪个更满足你的需要如何才是决定因素. [3 天烧脑式基于Docker的CI/ ...

  6. jquery访问ashx文件示例

    转自原文jquery访问ashx文件示例 .ashx 文件用于写web handler的..ashx文件与.aspx文件类似,可以通过它来调用HttpHandler类,它免去了普通.aspx页面的控件 ...

  7. Node.js 博客实例(一)简单博客

    原教程 https://github.com/nswbmw/N-blog/wiki/_pages的第一章.因为版本号等的原因,在原教程基础上稍加修改就可以实现. 环境: win7旗舰版64位 Node ...

  8. Wireshark默认不抓取本地包的解决方式

    事实上这个工具我已经用过非常多年了,还叫Ethereal的时候就在用. 今天因为实验须要,要抓一下在localhost间的包,结果发现获取不到.解决方法也非常easy,在cmd下输入: route a ...

  9. iOS开发—在@interface,@implementation和@property中变量的定义

    一直搞不懂在OC中变量在@interface和@implementation中有什么区别,定义@property又有什么不同,查了很多资料,总结如下: //ViewController.h @inte ...

  10. angular4(2-2)angular脚手架引入第三方类库(swiper)

    试了好多方法,npm install 方法失败了,下载到本地是可以使用的: 将swiper文件放到assets文件下: 项目目录下:(命令行) 因为ts并不能准确识别js语法,所以需要用ts中的int ...