CF1140G-Double Tree【最短路,矩阵乘法,树上倍增】

正题

题目链接:https://www.luogu.com.cn/problem/CF1140G


题目大意

给出一个nnn个点的树TTT,然后复制一份T′T'T,每个TTT中的点iiiT′T'T中的点iii都有连边构成一张图。

图上所有权值各不相同,现在qqq次询问图上两点的最短路。

1≤n≤3×105,1≤q≤6×1051\leq n\leq 3\times 10^5,1\leq q\leq 6\times 10^51n3×105,1q6×105


解题思路

因为树上两点简单路径唯一,所以xxxyyy之间的最短路肯定是包括两棵树中x∼yx\sim yxy路径上的某些点的。

现在问题就是从xxxx′x'x的切换问题,我们直接用最短路求出每个xxxx′x'x的最短距离,因为这样的距离肯定是在树上找一条点yyyxxx走到点yyy再从y′y'y走回x′x'x

然后设fi,j,p,qf_{i,j,p,q}fi,j,p,q表示从点iii出发往上跳了2j2^j2j步且原来在第ppp棵树上,现在在第kkk棵树上的方案。发现这个转移可以用矩阵乘法来优化。

然后求答案的时候找LCALCALCA的时候合并fff矩阵就好了。

时间复杂度:O((n+q)log⁡n)O((n+q)\log n)O((n+q)logn)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
#define mp(x,y) make_pair(x,y)
using namespace std;
const ll N=3e5+10,T=21,S=2;
struct edge{ll to,next,u,v;
}a[N<<1];
struct node{ll a[S][S];
}c,one,G[N][T];
ll n,Q,tot,ls[N],f[N],dep[N],g[N][T];
bool v[N];
priority_queue<pair<ll,ll> > q;
node operator*(const node &a,const node &b){memset(c.a,0x3f,sizeof(c.a));for(ll i=0;i<S;i++)for(ll j=0;j<S;j++)for(ll k=0;k<S;k++)c.a[i][j]=min(c.a[i][j],a.a[i][k]+b.a[k][j]);return c;
}
void addl(ll x,ll y,ll u,ll v){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].u=u;a[tot].v=v;return;
}
void dij(){for(ll i=1;i<=n;i++)q.push(mp(-f[i],i));while(!q.empty()){ll x=q.top().second;q.pop();if(v[x])continue;v[x]=1;for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(f[x]+a[i].u+a[i].v<f[y]){f[y]=f[x]+a[i].u+a[i].v;q.push(mp(-f[y],y));}}}return;
}
void dfs(ll x,ll fa){dep[x]=dep[fa]+1;for(ll i=ls[x];i;i=a[i].next){ll y=a[i].to;if(y==fa)continue;dfs(y,x);g[y][0]=x;G[y][0].a[0][0]=min(a[i].u,f[x]+f[y]+a[i].v);G[y][0].a[1][1]=min(a[i].v,f[x]+f[y]+a[i].u);G[y][0].a[0][1]=min(a[i].u+f[x],a[i].v+f[y]);G[y][0].a[1][0]=min(a[i].v+f[x],a[i].u+f[y]);}return;
}
node Ask(ll x,ll y){node X=one,Y=one;bool flag=0;if(x==y){X.a[0][0]=X.a[1][1]=0;X.a[0][1]=X.a[1][0]=f[x];return X;}if(dep[x]<dep[y])swap(x,y),flag=1;for(ll i=T-1;i>=0;i--)if(dep[g[x][i]]>=dep[y])X=X*G[x][i],x=g[x][i];if(x==y){if(flag)swap(X.a[0][1],X.a[1][0]);return X;}for(ll i=T-1;i>=0;i--)if(g[x][i]!=g[y][i])X=X*G[x][i],x=g[x][i],Y=Y*G[y][i],y=g[y][i];X=X*G[x][0];Y=Y*G[y][0];swap(Y.a[0][1],Y.a[1][0]);X=X*Y;if(flag)swap(X.a[0][1],X.a[1][0]);return X;
}
signed main()
{memset(one.a,0x3f,sizeof(one.a));one.a[0][0]=one.a[1][1]=0;scanf("%lld",&n);for(ll i=1;i<=n;i++)scanf("%lld",&f[i]);for(ll i=1,x,y,u,v;i<n;i++){scanf("%lld%lld%lld%lld",&x,&y,&u,&v);addl(x,y,u,v);addl(y,x,u,v);}dij();dfs(1,0);for(ll j=1;j<T;j++)for(ll i=1;i<=n;i++){g[i][j]=g[g[i][j-1]][j-1];G[i][j]=G[i][j-1]*G[g[i][j-1]][j-1];}scanf("%lld",&Q);while(Q--){ll x,y;scanf("%lld%lld",&x,&y);node tmp=Ask((x+1)/2,(y+1)/2);printf("%lld\n",tmp.a[!(x&1)][!(y&1)]);}return 0;
}

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

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

相关文章

数论六之计算几何——An Easy Problem,Ancient Berland Circus,Open-air shopping malls

可检验模板正确度An Easy Problem?!Ancient Berland CircusOpen-air shopping mallsAn Easy Problem?! problem 就是大讨论 #include <cmath> #include <cstdio> #include <iostream> using namespace std; #define eps 1e-6struct vec {double x, y;ve…

CodeForces:12271261(div1)1262(div2)

文章目录前言CF1227A Math ProblemDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text{Code}CodeCF1227B BoxDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text{Code}CodeCF1227C MessyDescription\text{Des…

【NET CORE微服务一条龙应用】应用部署

简介本章主要介绍https://github.com/q315523275/FamilyBucket上微服务一条龙应用&#xff0c;在实际使用中的应用部署&#xff0c;以原始方式部署非docker部署应用主要包括&#xff1a;1、网关应用部署2、授权认证应用部署3、配置中心查询服务端应用部署4、综合管理应用部署5、…

牛客网区间dp练习

NC13230 合并回文子串 NC16129 小小粉刷匠 NC19909 [CQOI2007]涂色PAINT NC19997 [HAOI2016]字符合并 NC20238 [SCOI2003]字符串折叠 NC20252 [SCOI2007]压缩 NC20312 [SDOI2008]SUE的小球 POJ3042 Grazing on the Run

CF516D-Drazil and Morning Exercise【树上差分,倍增】

正题 题目链接:https://www.luogu.com.cn/problem/CF516D 题目大意 给出一棵nnn个点的树&#xff0c;定义f(x)f(x)f(x)表示距离点xxx最远的点的距离&#xff0c;qqq次询问给出一个kkk&#xff0c;要求一个最大的连通块满足连通块中所有点的f(x)f(x)f(x)最大最小差值不能超过k…

容斥问卷调查反馈——Co-prime,Character Encoding,Tree and Constraints,「2017 山东一轮集训 Day7」逆序对

文章目录Co-primesourcesolutioncodeCharacter EncodingsourcesolutioncodeTree and Constraintssourcesolutioncode「2017 山东一轮集训 Day7」逆序对sourcesolutioncodeCo-prime source TTT组数据&#xff0c;给出&#x1d43f;,&#x1d445;,&#x1d441;&#x1d43f;, …

手工修复Azure DevOps无法连接到Azure的问题

点击上方蓝字关注“汪宇杰博客”今天我在为一个从TFVC迁移到Git的老项目重新配置发布到Azure App Service的CI/CD管线的时候&#xff0c;Azure DevOps竟然爆了。这是一个微软已知的bug&#xff0c;目前还未修复&#xff0c;我来带大家看看如何手工workaround这个问题。首先&…

Loj#576-「LibreOJ NOI Round #2」签到游戏【线段树】

正题 题目链接:https://loj.ac/p/576 题目大意 给出一个长度为nnn的序列aaa&#xff0c;还有一个未知序列bbb&#xff0c;你每次可以花费gcd⁡ilrai\gcd_{il}^r a_igcdilr​ai​的代价得到∑ilrbi\sum_{il}^rb_i∑ilr​bi​的值。 每次修改aaa中的一个数&#xff0c;求得到b…

NC14732 锁

NC14732 锁 题意&#xff1a; n个居民&#xff0c;门上有k把锁&#xff0c;每个居民有若干钥匙&#xff0c;为1到k的一个子集&#xff0c;如果几名居民的钥匙的并集是1到k&#xff0c;即他们拥有全部锁的对应钥匙。 求最小的k&#xff0c;使得可以适当地给居民们每人若干钥匙…

CodeForces:1103(div1)1104(div2)

文章目录前言CF1104A Splitting into digitsDescription\text{Description}DescriptionSolution\text{Solution}SolutionDescription\text{Description}DescriptionCF1104B Game with stringDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text…

专题突破一之分块——Untitled Problem II,Balanced Lineup,[ioi2009]Regions

文章目录SP2940 UNTITLE1 - Untitled Problem IIsourcesolutioncodeBalanced LineupsourcecodeCount on a tree II[ioi2009]RegionsSP2940 UNTITLE1 - Untitled Problem II source solution 分块 si{sik(i−l1)sikik(1−l)l≤i≤rsik(r−l1)r<is_i\begin{cases} s_ik\tim…

.NET Core实战项目之CMS 第十七章 CMS网站系统的部署

目前我们的.NET Core实战项目之CMS系列教程基本走到尾声了&#xff0c;通过这一系列的学习你应该能够轻松应对.NET Core的日常开发了&#xff01;当然这个CMS系统的一些逻辑处理还需要优化&#xff0c;如没有引入日志组件以及缓存功能&#xff0c;权限目前只支持控制到菜单&…

ICPC2019南昌区域赛

ICPC2019南昌区域赛 题号题目知识点难度A9102BA Funny Bipartite Graph状压dp思维稳银快金CAnd and Pair二项式定理快铜DBitwise TreeEBob’s Problem思维&#xff0c;生成树签到FDynamic Suffix ArrayGEating Plan思维题稳铜快银HPowers of TwoIResistanceJSummonKTreeLWho i…

Loj#510-「LibreOJ NOI Round #1」北校门外的回忆【线段树】

正题 题目链接:https://loj.ac/p/510 题目大意 给出一个代码 function add(x,v)while x < n dos[x] s[x] xor vx x lowbit(x) //注意&#xff0c;这里是 lowbit&#xff0c;这也是两份代码唯一的区别end while end functionfunction query(x)ans 0while x > 0 doa…

如何用EFCore Lazy Loading实现Entity Split

α角 与 β角支持 现实生活 的 计算机系统&#xff0c;总有着两大偏差&#xff0c;第一个是 现实生活 与 计算机系统 的α角&#xff0c;另外一个是计算机系统的 逻辑设计 与 物理设计 的β角。举个栗子&#xff1a;α角&#xff1a;假设某个公司的商业流程&#xff0c;我们在做…

CodeForces:372(div1)div373(div2)

文章目录前言CF373A Collecting Beats is FunDescription\text{Description}DescriptionSolution\text{Solution}SolutionCode\text{Code}CodeCF373B Making Sequences is FunDescription\text{Description}DescriptionSolution\text{Solution}SolutionCF372A Counting Kangaro…

一二三系列之CodeChef分块——Chef and Churu,Chef and Problems,Children Trips

文章目录Chef and ChurusourcesolutioncodeChef and ProblemssourcesolutioncodeChildren TripssourcesolutioncodeChef and Churu source solution 对于单独的iii&#xff0c;查询可以用线段树/树状数组O(nlog⁡n)O(n\log n)O(nlogn)&#xff0c;这暗示可以平衡查询修改次数…

Bob‘s Problem

Bob’s Problem 题意&#xff1a; 一个有n个点的图&#xff0c;其中边分为白色和黑色&#xff0c;每个边都有边权&#xff0c;所选白边的数量的数量不能超过k&#xff0c;问现在选择一些边&#xff0c;使得所有点连通&#xff0c;问最大权值是多少&#xff1f; 题解&#xf…

.NET Core 开源项目 Anet 在路上

今天给大家介绍我刚开源的一个 .NET Core 项目&#xff1a;Anet。Anet 的目标是实现一个 .NET Core 通用库、通用框架和通用模板。我给它的定义是&#xff1a;A .NET Core Common Lib, Framework and Boilerplate.它的取名正是来自于这句话的前面四个字母&#xff1a;ANET。Ane…

Loj#2324-「清华集训 2017」小 Y 和二叉树

正题 题目链接:https://loj.ac/p/2324 题目大意 给出nnn个点的一棵树&#xff0c;每个点的度数不超过333。 你要求它的一个二叉树结构&#xff08;根任意选择&#xff09;使得其中序遍历的字典序最小。 1≤n≤1061\leq n\leq 10^61≤n≤106 解题思路 直接找根感觉比较麻烦&…