洛谷P2680:运输计划(倍增、二分、树上差分)

传送门

文章目录

  • 题目描述
  • 解析
  • 问题
  • 代码

题目描述

在这里插入图片描述

解析

求最大值的最小值
容易想到二分
然后。。。就没有然后了。。。
看了题解
学会了一个新技能:树上差分
(其实学长之前好像讲过。。。)

一般的,对于一条A到B的路径,如果要将其全部加上一个值w。我们可以把AB两点的前缀加w,再把它们的lca及lca的父亲减去w,最后统计时用dfs统计,每个点的价值就是其本身及子树的前缀值之和
画个图就能很直观的看出来,请读者自行动笔探究~~(绝对不是我懒)~~
lca可以用许多算法优化到log,这样时间复杂度就很优秀啦

本题对于一个二分出来的值mid,如果有一些路径的长度大于mid,那么删的边一定是这些不符合的路径的公共边(不然它还是不符合)
就相当与每次把不符合的路径上的点全部加1,再统计点权恰好等于不符合路径个数的点,它们之间的边,就是可以删的边(这就能用差分啦)
其中选一条最大的,看减完它行不行即可

问题

本题到这里思路就结束了
但真正做起来真的有点搬砖。。。
还遇到了很多细节问题

1.树上倍增的时候要注意单链时最后不用再跳一边father了!
2.300000的log大于15(我掰手指头当成30000了。。。调了好久)
3.双向边要开二倍!!!!

这都是经常遇到的问题,代码复杂起来就又忘了,一定要引以为戒,注意细节!

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=3e5+100;
int n,m;
struct node{int to,nxt,v;
}p[2*N];
int fi[N],cnt=-1;
void addline(int x,int y,int v){p[++cnt]=(node){y,fi[x],v};fi[x]=cnt;
}int dep[N],fa[N],fv[N];
void dfs(int x,int f){for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(to==f) continue;fa[to]=x;dep[to]=dep[x]+1;fv[to]=p[i].v;dfs(to,x);}return;
}
int pl[22][N],dis[22][N],mi[22];
void solve(){mi[0]=1;for(int i=1;i<=20;i++) mi[i]=mi[i-1]*2;for(int i=2;i<=n;i++){pl[0][i]=fa[i];dis[0][i]=fv[i];}for(int k=1;k<=20;k++){for(int i=1;i<=n;i++){if(dep[i]<mi[k]) continue;pl[k][i]=pl[k-1][pl[k-1][i]];dis[k][i]=dis[k-1][i]+dis[k-1][pl[k-1][i]];}}return;
}
int place,tot;
void find(int x,int y){tot=0;if(dep[x]<dep[y]) swap(x,y);for(int k=20;k>=0;k--){if(dep[x]-mi[k]>=dep[y]){tot+=dis[k][x];x=pl[k][x];}}for(int k=20;k>=0;k--){if(dep[x]<mi[k]||pl[k][x]==pl[k][y]) continue;tot+=dis[k][x];x=pl[k][x];tot+=dis[k][y];y=pl[k][y];
//		printf("x=%d y=%d tot=%d\n",x,y,tot);}place=x;if(x!=y){tot+=fv[x];tot+=fv[y];place=fa[place];}
}struct node2{int x,y,len,lca;
}q[N];
int a,b,c;int num;
int pre[N],sum[N];
void dfs2(int x,int f,int &ans){sum[x]=pre[x];for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(to==f) continue;dfs2(to,x,ans);sum[x]+=sum[to];}if(sum[x]!=num) return;for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(sum[to]==num){ans=max(ans,p[i].v);
//			printf("x=%d y=%d v=%d\n",x,to,fv[to]);}}return;
}
bool check(int mid){int mx=0;num=0;memset(pre,0,sizeof(pre));memset(sum,0,sizeof(sum));
//	printf("check: (%d)\n",mid);for(int i=1;i<=m;i++){if(q[i].len>mid){num++;mx=max(mx,q[i].len);pre[q[i].x]++;pre[q[i].y]++;pre[q[i].lca]--;pre[fa[q[i].lca]]--;}}if(num==0) return true;int ans=0;dfs2(1,0,ans);
//	printf("  num=%d ans=%d\n",num,ans);if(mx-ans<=mid) return true;else return false;
}
int main(){memset(fi,-1,sizeof(fi));
//	printf("%d",sizeof(pl)/1024/1024);scanf("%d%d",&n,&m);for(int i=1;i<n;i++){scanf("%d%d%d",&a,&b,&c);addline(a,b,c);addline(b,a,c);}dfs(1,0);solve();
//	for(int i=1;i<=n;i++) printf("i=%d fa=%d dep=%d\n",i,fa[i],dep[i]);for(int i=1;i<=m;i++){scanf("%d%d",&a,&b);find(a,b);q[i]=(node2){a,b,tot,place};
//		printf("tot=%d pl=%d\n",tot,place);}int st=0,ed=2e9;while(st<ed){
//		printf("st=%d ed=%d\n",st,ed);int mid=(st+ed)>>1;if(check(mid)) ed=mid;else st=mid+1;}printf("%d",st);
}
/*
12 3
1 2 8
1 3 1
1 4 8
2 5 6
2 7 5
2 6 4
6 8 7
6 9 5
3 10 6
3 12 3
10 11 5
1 11
3 11
10 116 4
1 2 3 
1 6 4 
3 1 7 
4 3 6 
3 5 5 
3 6 
2 5 
4 5
2 4
*/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318482.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算几何基础-2

文章目录直线&#xff1a;图形&#xff1a;求垂足求两圆交点直线与圆交点多边形问题判断一个点是否在任意多边形内部Pick定理凸包求点集的凸包水平法&#xff1a;增量法&#xff1a;半平面半平面交求半平面交直线&#xff1a; struct Line{point p,v;Line(){}Line(point _p.po…

eShopOnContainers 看微服务 ②:配置 启动

一、什么是dockerDocker 是一个开源项目&#xff0c;通过把应用程序打包为可移植的、自给自足的容器&#xff08;可以运行在云端或本地&#xff09;的方式&#xff0c;实现应用程序的自动化部署。使用 Docker 的时候&#xff0c;需要创建一个应用或服务&#xff0c;然后把它和它…

判断整除(opj)(动态规划)

解析 与取模结合的动归&#xff0c;正常做即可 问题 眼瞎&#xff01;&#xff01;&#xff01; 这个序列的每个数都必须用到&#xff01;&#xff01;&#xff01; if(f[i-1][j]) f[i][j]1;上面这行就是不对的&#xff01;&#xff01;&#xff01; 头疼 仔细审题 opj的题…

[USACO09FEB]Revamping Trails G

题意&#xff1a; 约翰一共有 N 个牧场.由 MM 条布满尘埃的小径连接。小径可以双向通行。每天早上约翰从牧场 1 出发到牧场 N 去给奶牛检查身体。 通过每条小径都需要消耗一定的时间。约翰打算升级其中 K 条小径&#xff0c;使之成为高速公路。在高速公路上的通行几乎是瞬间完…

NET Core微服务之路:自己动手实现Rpc服务框架,基于DotEasy.Rpc服务框架的介绍和集成...

本篇内容属于非实用性&#xff08;拿来即用&#xff09;介绍&#xff0c;如对框架设计没兴趣的朋友&#xff0c;请略过。 快一个月没有写博文了&#xff0c;最近忙着两件事;一&#xff1a;阅读刘墉先生的《说话的魅力》&#xff0c;以一种微妙的&#xff0c;你我大家都会经常遇…

花店橱窗布置(洛谷P1854)(动态规划)

传送门 文章目录解析问题代码解析 一道很正常的动态规划 dp[i][j]表示到第j个花瓶放了第j朵花的dp最优值 注意&#xff1a;是严格使第i朵放在j瓶 找到最优解递归输出即可 问题 又是初始化的问题&#xff01;&#xff01;&#xff01; 一开始把dp赋值成负无穷时落掉了j0的一行…

P4009 汽车加油行驶问题

题目描述&#xff1a; 题解&#xff1a; 看了很多题解&#xff0c;无论什么解法都绕不开分层图 在本题中加满油的车每次可以移动K步&#xff0c;那么我们就可以建立一个K1层的分层图&#xff0c;表示汽车油量k的状态&#xff08;油量0…k&#xff09;&#xff0c;然后根据题目…

.net core i上 K8S(五).netcore程序的hostip模式

正文上一章讲了pod的管理&#xff0c;今天再分享一个pod的访问方式1.Pod的HostIP模式Pod的HostIP模式&#xff0c;可以通过宿主机访问pod内的服务&#xff0c;创建yaml文件如下apiVersion: v1 kind: Pod metadata: name: netcore-podlabels:app: netcorepod spec:containers: …

状态压缩:枚举子集(最优组队)(ybtoj)(动态规划)

解析 很裸的状压dp 但是直接暴力的话状态2n,枚举2n 乘在一起会T诶 怎么办呢&#xff1f; 使用下面这个循环&#xff0c;就可以保证只会枚举当前状态s的子集 for(int i(s-1)&s;i;i(i-1)&s){........ }证明 举举例子就挺明显了 为什么不重不漏呢&#xff1f; 首先i肯…

【活动(深圳)】告别2018之12.22 大湾区.NET Meet 大会 ,同时有网络直播

今年的 Connect(); 主题更加聚焦开发者工具生产力、开源&#xff0c;以及无服务器&#xff08;Serverless&#xff09;云服务。Visual Studio 2019 AI 智能加持的 IntelliCode、实时代码协作共享 Live Share&#xff0c;.NET Core 3.0的预览版本附带了大量更新&#xff0c;旨在…

最短路径(状压dp)(ybtoj)

解析 “bug总有de完的一天” 头疼 暴力写的话本题显然复杂度是假的 有一个很好的思路优化时间复杂度 先用dp[k][i]表示**从第k个关键点到任意i点的最短路 跑k遍 SPFA或迪杰斯特拉 即可 然后转移时可以只考虑关键点 使状态转移数大大降低 细节 头真疼 边界条件&#xff1a; …

P2403 [SDOI2010]所驼门王的宝藏(强连通分量)(拓扑排序)

文章目录题目描述解析代码洛谷传送门题目描述 解析 看题目要求很容易想到强连通分量缩点加拓扑dp 但是问题在于存图 第一感就是和暴力和每个点连边 但那样无论点数和边数都很爆炸 随后我们发现这个图非常稀疏 所以我们可以只连有宝藏的点 然而这样边数会被一行横门这样的数据…

Xamarin.Forms之UserDialogs 重制版本

在 forms 里面&#xff0c;目前使用比较多的弹出组件是 Acr.UserDialogs &#xff0c;但是这个组件有些小问题&#xff0c;比如 loading .hide 会同时把 toast 给一起关掉&#xff0c;android 下的 toast 希望是 安卓原生的toast 样子&#xff0c;而不是 底部弹出一个横条&…

H.Minimum-cost Flow

H.Minimum-cost Flow 题目&#xff1a; 其实就是给出每条边的单位费用&#xff0c;q次查询&#xff0c;每次查询改变所有边的容量&#xff08;所有边容量一样&#xff09;&#xff0c;问最后流出1流量的最小花费是多少&#xff1f; 题解&#xff1a; 暴力做法肯定是每次询问…

eShopOnContainers 看微服务③:Identity Service

引言通常&#xff0c;服务所公开的资源和 API 必须仅限受信任的特定用户和客户端访问。那进行 API 级别信任决策的第一步就是身份认证——确定用户身份是否可靠。在微服务场景中&#xff0c;身份认证通常统一处理。一般有两种实现形式&#xff1a;基于API 网关中心化认证&#…

P2168 [NOI2015] 荷马史诗(哈夫曼编码树)

传送门 文章目录题目描述解析细节代码题目描述 解析 其实就是构造一棵树 另所有带权点都为叶子节点 其代价为权值与深度的乘积 求最小代价及最小代价下的最小深度 可以看成一开始有n棵小树 每次把k棵合并在一起 最后合成一棵大树就行了 每次合并的代价是k棵树的权值和 看到这…

B-Suffix Array

B-Suffix Array 题意&#xff1a; 一个字符串只含有a和b&#xff0c;先给出b数组的构造方式&#xff1a; 对于每个位置i来说&#xff1a; 如果存在一个位置j&#xff0c;使得j<i,且s[j] s[i],则b[i]i-j否则b[i]0 现在对字符串每个后缀都构造B数组&#xff0c;并按照字典…

线段树合并、分裂

基本概念&#xff1a; 如果需要维护许多个大小为 \(10^5\) 级别的多重集&#xff0c;可以看做给每一个多重集建立一棵线段树。线段树的合并、分裂就是多重集的累加、分开。 这里使用动态开点的方式存储线段树树。 如果一个节点为空&#xff0c;那么它的编号为 \(0\) 。 变量释义…

(神奇的)虚树(初步了解)

参考文献&#xff1a; 博文1 博文2 博文3 引入 在一类树上动态规划问题中,题目给出的询问往往包含树上的很多各节点,并保证总的点数规模小于某个值. 如果我们直接在整颗树上进行dp的话,时间复杂度与询问的次数有关,这显然是不可接受的,如果我们可以找到一种动态规划的方法,使…

P2048 [NOI2010] 超级钢琴(RMQ 贪心)

文章目录题目描述解析代码传送门题目描述 解析 首先&#xff0c;如果只有一个和弦&#xff0c;那么问题显然简单了 用前缀和结合ST表随便做做即可 然而 这次要求前k大的 怎么办呢&#xff1f; 参照之前有一道序列合并的做法 我们想到&#xff0c;可以先建一个优先队列&#xf…