C120 树剖+李超树 P4069 [SDOI2016] 游戏

news/2024/9/24 21:27:02

视频链接:

 

 

 

 

D12 Luogu P3384【模板】轻重链剖分/树链剖分 - 董晓 - 博客园 (cnblogs.com) 

Luogu P4069 [SDOI2016] 游戏

// 树剖+李超树 O(nlognlognlogn)
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;typedef long long ll;
#define ls u<<1
#define rs u<<1|1
const int N=100005;
const ll INF=123456789123456789;int tot,head[N],to[N<<1],ne[N<<1],w[N<<1];
void add(int a,int b,int c){to[++tot]=b;w[tot]=c;ne[tot]=head[a];head[a]=tot;
}
int fa[N],son[N],dep[N],siz[N]; //树剖数组
int top[N],dfn[N],old[N],tim;
ll dis[N]; //到树根的距离void dfs1(int u,int f){fa[u]=f,dep[u]=dep[f]+1,siz[u]=1;for(int i=head[u];i;i=ne[i]){int v=to[i];if(v==f) continue;dis[v]=dis[u]+w[i];dfs1(v,u);siz[u]+=siz[v];if(siz[son[u]]<siz[v]) son[u]=v;}
}
void dfs2(int u,int tp){top[u]=tp,dfn[u]=++tim,old[tim]=u;if(son[u]) dfs2(son[u],tp);for(int i=head[u];i;i=ne[i]){int v=to[i];if(v==fa[u]||v==son[u])continue;dfs2(v,v);}
}
int LCA(int u,int v){while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]]) swap(u,v);u=fa[top[u]];}return dep[u]<dep[v]?u:v;
}int n,m,cnt;
struct line{ //线段int k; ll b;line(){k=0,b=INF;}line(int x,ll y){k=x,b=y;}
}p[N<<1];struct tree{ //李超树int id;    //优势线段的编号ll mi;     //最小值tree(){mi=INF;}
}tr[N<<3];   //因访问叶子节点的儿子,故开8倍空间

ll Y(int id,ll x){ //求Y值return p[id].k*x+p[id].b;
}
void pushup(int u,int l,int r){ //上传ll ans=min(Y(tr[u].id,dis[old[l]]),Y(tr[u].id,dis[old[r]]));tr[u].mi=min(ans,min(tr[ls].mi,tr[rs].mi));
}
void change(int u,int l,int r,int L,int R,int id){ //区修int mid=(l+r)>>1;if(L<=l&&r<=R){if(Y(id,dis[old[mid]])<Y(tr[u].id,dis[old[mid]])) swap(id,tr[u].id);if(Y(id,dis[old[l]])<Y(tr[u].id,dis[old[l]])) change(ls,l,mid,L,R,id);if(Y(id,dis[old[r]])<Y(tr[u].id,dis[old[r]])) change(rs,mid+1,r,L,R,id);pushup(u,l,r);return;}if(L<=mid) change(ls,l,mid,L,R,id);if(R>mid) change(rs,mid+1,r,L,R,id);pushup(u,l,r);
}
void treechange(int u,int v,int id){ //树修while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]]) swap(u,v);change(1,1,n,dfn[top[u]],dfn[u],id);u=fa[top[u]]; //爬链
  }if(dep[u]>dep[v]) swap(u,v);change(1,1,n,dfn[u],dfn[v],id); //最后一段
}
ll query(int u,int l,int r,int L,int R){ //区查if(L<=l&&r<=R) return tr[u].mi;int mid=(l+r)>>1;ll ans=min(Y(tr[u].id,dis[old[max(l,L)]]),Y(tr[u].id,dis[old[min(r,R)]]));if(L<=mid) ans=min(ans,query(ls,l,mid,L,R));if(R>mid) ans=min(ans,query(rs,mid+1,r,L,R));return ans;
}
ll treequery(int u,int v){ //树查ll ans=INF;while(top[u]!=top[v]){if(dep[top[u]]<dep[top[v]]) swap(u,v);ans=min(ans,query(1,1,n,dfn[top[u]],dfn[u]));u=fa[top[u]]; //爬链
  }if(dep[u]>dep[v]) swap(u,v);return min(ans,query(1,1,n,dfn[u],dfn[v]));
}
int main(){scanf("%d%d",&n,&m);for(int i=1,u,v,w; i<=n-1; i++)scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,w);dfs1(1,0),dfs2(1,1);for(int i=1,op,s,t; i<=m; i++){scanf("%d%d%d",&op,&s,&t);if(op==1){int a,b,lca;scanf("%d%d",&a,&b); lca=LCA(s,t);p[++cnt]=line(-a,a*dis[s]+b);treechange(s,lca,cnt);p[++cnt]=line(a,a*(dis[s]-2*dis[lca])+b);treechange(lca,t,cnt);}else printf("%lld\n",treequery(s,t));}
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

ABAQUS 中的一些约定

404目录自由度notationAxisymmetric elementsActivation of degrees of freedomInternal variables in Abaqus/StandardCoordinate systemsSymbols used in Abaqus for unitsTime measuresConvention used for stress and strain componentsNonisotropic material behaviorZero…

如何快速提取出一个文件里面全部指定类型的文件的全部路径

首先,需要用到的这个工具:度娘网盘 提取码:qwu2 蓝奏云 提取码:2r1z打开工具,切换到第五个模块,文件批量复制模块(快捷键:Ctrl+5)点击右边的“搜索添加”按钮,我这里就从我的PS文件夹里面找出全部的jpg图片叭,勾选两项,搜文件,并且搜全部子文件,然后点开始搜索按…

夜莺监控(Nightingale)上线内置指标功能

Prometheus 生态里如果要查询数据,需要编写 promql,对于普通用户来说,门槛有点高。通常有两种解法,一个是通过 AI 的手段做翻译,你用大白话跟 AI 提出你的诉求,让 AI 帮你写 promql,另一种是平台里内置现成的 promql,覆盖常用场景开箱即用。夜莺监控(Nightingale)最近…

运算符与表达式

运算符与表达式 Created: November 29, 2023 10:38 PM 运算符运算符 释义+、-、*、/ 略**、//、% 乘方、整除(向下取整至最接近的整数、余数<<、>> 指的是二进制左右移&按位与 按位与是针对二进制数的操作,指将两个二进制数的每一位都进行比较,如果两个相应…

部署Prometheus Operator完整流程及踩坑解决思路

环境信息软件 版本号Linux Centos7.9k8s v1.26.9Docker 25.0.4kube-prometheus v0.13.0nginx-ingress-controller v1.10.1K8S集群信息(提前安装好自己的集群,本文不再讲解集群的安装)主机名 IPk8s-master 192.168.2.11k8s-node01 192.168.2.12k8s-node02 192.168.2.13一、安装…

R语言中如何将科学计数法转换为数值型

001、测试a <- c("1.23e-2", "7.56207e-05", "6.86470e-05") as.numeric(a) ## 直接转换为数值类型, 然而并不起作用 02、增加参数options(scipen = 100) ## 小数点后100位不适用科学计数法 b <- c("1.23e-2", &q…

JavaSE之java基础语法

关键字和保留字 关键字定义和特点 定义:被java语言赋予了特殊含义,用作专门用途的字符串。 特点:关键字中所有字母都为小写。关键字不能用作变量名,方法名,类名,包名和参数。用于定义数字类型的关键字 class interface enum byte short int long float double char bo…