题意

显然树剖套李超树。

考虑怎么算函数值:

设\((x,y)\)的\(lca\)为\(z\),我们插一条斜率为\(k\),截距为\(b\)的线段。

\((x,z)\)上的点\(u\):

\(f(u)=k*(dis[x]-dis[u])+b=-k*dis[u]+(k*dis[x]+b)\)

所以对这条路径插入斜率为\(-k\),截距为\(k*dis[x]+b\)的线段

\((y,z)\)上的点\(u\):

\(f(u)=k*(dis[y]+dis[u]-2*dis[z])+b=k*dis[u]+k*(dis[y]-2*dis[z])+b\)

同理

code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
#define minn(p)(seg[p].minn)
#define minid(p) (seg[p].minid)
const int maxn=100010;
const int inf=123456789123456789ll;
int n,m,cnt,tim;
int head[maxn],dep[maxn],dfn[maxn],pos[maxn],size[maxn],son[maxn],pre[maxn],top[maxn],dis[maxn];
struct edge{int to,nxt,dis;}e[maxn<<1];
struct Line
{
int k,b;
inline int calc(int x){return k*x+b;}
};
struct Seg{int minn;Line minid;}seg[maxn<<2];
inline int read()
{
char c=getchar();int res=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')res=res*10+c-'0',c=getchar();
return res*f;
}
inline void add(int u,int v,int w)
{
e[++cnt].nxt=head[u];
head[u]=cnt;
e[cnt].to=v;
e[cnt].dis=w;
}
void dfs1(int x,int fa)
{
pre[x]=fa;dep[x]=dep[fa]+1;size[x]=1;
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(y==fa)continue;
dis[y]=dis[x]+e[i].dis;
dfs1(y,x);size[x]+=size[y];
if(size[son[x]]<size[y])son[x]=y;
}
}
void dfs2(int x,int tp)
{
top[x]=tp;dfn[x]=++tim;pos[tim]=x;
if(son[x])dfs2(son[x],tp);
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
if(y==pre[x]||y==son[x])continue;
dfs2(y,y);
}
}
inline int lca(int x,int y)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=pre[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
return x;
}
inline void up(int p){minn(p)=min(minn(p),min(minn(ls(p)),minn(rs(p))));}
void build(int p,int l,int r)
{
minn(p)=inf;minid(p)=(Line){0,inf};
if(l==r)return;
int mid=(l+r)>>1;
build(ls(p),l,mid);build(rs(p),mid+1,r);
}
inline void move(int p,int l,int r,Line id)
{
int nowl=minid(p).calc(dis[pos[l]]),nowr=minid(p).calc(dis[pos[r]]);
int tmpl=id.calc(dis[pos[l]]),tmpr=id.calc(dis[pos[r]]);
if(nowl<=tmpl&&nowr<=tmpr)return;
if(nowl>=tmpl&&nowr>=tmpr)
{
minid(p)=id;minn(p)=min(minn(p),min(tmpl,tmpr));
return;
}
double point=1.0*(minid(p).b-id.b)/(1.0*(id.k-minid(p).k));
int mid=(l+r)>>1;
if(tmpl>nowl)
{
if(point<=(double)dis[pos[mid]])move(ls(p),l,mid,minid(p)),minid(p)=id;
else move(rs(p),mid+1,r,id);
}
else
{
if(point<=(double)dis[pos[mid]])move(ls(p),l,mid,id);
else move(rs(p),mid+1,r,minid(p)),minid(p)=id;
}
minn(p)=min(minn(p),min(tmpl,tmpr));
up(p);
}
void change(int p,int l,int r,int ql,int qr,Line id)
{
if(l>=ql&&r<=qr){move(p,l,r,id);return;}
int mid=(l+r)>>1;
if(ql<=mid)change(ls(p),l,mid,ql,qr,id);
if(qr>mid)change(rs(p),mid+1,r,ql,qr,id);
up(p);
}
int query(int p,int l,int r,int ql,int qr)
{
if(l>=ql&&r<=qr)return minn(p);
int mid=(l+r)>>1,res=min(minid(p).calc(dis[pos[max(l,ql)]]),minid(p).calc(dis[pos[min(r,qr)]]));
if(ql<=mid)res=min(res,query(ls(p),l,mid,ql,qr));
if(qr>mid)res=min(res,query(rs(p),mid+1,r,ql,qr));
return res;
}
inline void trchange(int x,int y,int k,int b)
{
while(top[x]!=top[y])
{
change(1,1,n,dfn[top[x]],dfn[x],(Line){k,b});
x=pre[top[x]];
}
change(1,1,n,dfn[y],dfn[x],(Line){k,b});
}
inline void trsolve(int x,int y,int k,int b)
{
int z=lca(x,y);
trchange(x,z,-k,k*dis[x]+b);
trchange(y,z,k,k*(dis[x]-(dis[z]<<1))+b);
}
inline int trquery(int x,int y)
{
int res=inf;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
res=min(res,query(1,1,n,dfn[top[x]],dfn[x]));
x=pre[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
res=min(res,query(1,1,n,dfn[x],dfn[y]));
return res;
}
signed main()
{
//freopen("test.in","r",stdin);
//freopen("test.out","w",stdout);
n=read(),m=read();
for(int i=1;i<n;i++)
{
int u=read(),v=read(),w=read();
add(u,v,w),add(v,u,w);
}
dfs1(1,0),dfs2(1,1);
build(1,1,n);
for(int i=1;i<=m;i++)
{
int op=read(),x=read(),y=read(),k,b;
if(op==1)k=read(),b=read(),trsolve(x,y,k,b);
else printf("%lld\n",trquery(x,y));
}
return 0;
}

luoguP4069 [SDOI2016]游戏的更多相关文章

  1. 4515: [Sdoi2016]游戏

    4515: [Sdoi2016]游戏 链接 分析: 树链剖分 + 超哥线段树.注意细节. 代码: #include<cstdio> #include<algorithm> #i ...

  2. 【BZOJ4515】[Sdoi2016]游戏 树链剖分+线段树

    [BZOJ4515][Sdoi2016]游戏 Description Alice 和 Bob 在玩一个游戏. 游戏在一棵有 n 个点的树上进行.最初,每个点上都只有一个数字,那个数字是 1234567 ...

  3. BZOJ4515: [Sdoi2016]游戏

    Description Alice 和 Bob 在玩一个游戏. 游戏在一棵有 n 个点的树上进行.最初,每个点上都只有一个数字,那个数字是 123456789123456789. 有时,Alice 会 ...

  4. bzoj 4515: [Sdoi2016]游戏

    Description Alice 和 Bob 在玩一个游戏. 游戏在一棵有 n 个点的树上进行.最初,每个点上都只有一个数字,那个数字是 123456789123456789. 有时,Alice 会 ...

  5. [SDOI2016]游戏

    Description Alice 和 Bob 在玩一个游戏. 游戏在一棵有 n 个点的树上进行.最初,每个点上都只有一个数字,那个数字是 123456789123456789. 有时,Alice 会 ...

  6. [bzoj4515][Sdoi2016]游戏-树链剖分+李超线段树

    Brief Description Alice 和 Bob 在玩一个游戏. 游戏在一棵有 n 个点的树上进行.最初,每个点上都只有一个数字,那个数字是 123456789123456789. 有时,A ...

  7. bzoj千题计划276:bzoj4515: [Sdoi2016]游戏

    http://www.lydsy.com/JudgeOnline/problem.php?id=4515 把lca带进式子,得到新的式子 然后就是 维护树上一次函数取min 一个调了一下午的错误: 当 ...

  8. 【题解】Luogu P4069 [SDOI2016]游戏

    原题传送门 看到这种题,想都不用想,先写一个树链剖分 然后发现修改操作增加的是等差数列,这使我们想到了李超线段树 先进性树剖,然后用李超线段树维护区间最小,这样就做完了(写码很容易出错) 复杂度为\( ...

  9. BZOJ.4515.[SDOI2016]游戏(树链剖分 李超线段树)

    BZOJ 洛谷 每次在路径上加的数是个一次函数,容易看出是树剖+李超线段树维护函数最小值.所以其实依旧是模板题. 横坐标自然是取个确定的距离标准.取每个点到根节点的距离\(dis[i]\)作为\(i\ ...

随机推荐

  1. Codeforces Round #597 (Div. 2) F. Daniel and Spring Cleaning 数位dp

    F. Daniel and Spring Cleaning While doing some spring cleaning, Daniel found an old calculator that ...

  2. 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 3

    18.3  PDO的安装 PDO随PHP 5.1版本发行,在PHP 5的PECL扩展中也可以使用.PDO需要PHP 5版本核心面向对象特性的支持,所以它无法在之前的PHP版本中运行.无论如何,在配置P ...

  3. javascript实现base64编码、解码

    我们知道,浏览器的window对象提供有window.atob()和window.btoa()方法可以对字符串进行Base64编码和解码. console.log(window.btoa(window ...

  4. Mac 应用程序不能打开解决方法

    Mac 应用程序不能打开解决方法 关键是 文件原本是可执行文件,由于权限丢失,才变成了类型不明的文件,导致软件无法打开. 参考: https://www.macbl.com/article/tips/ ...

  5. 实例演示 C# 中 Dictionary<Key, Value> 的检索速度远远大于 hobbyList.Where(c => c.UserId == user.Id)

    前言 我们知道,有时候在一些项目中,为了性能,往往会一次性加载很多条记录来进行循环处理(备注:而非列表呈现).比如:从数据库中加载 10000 个用户,并且每个用户包含了 20  个“爱好”,在 Wi ...

  6. 【mysql】Mysql5.7--sys_schema视图

    前言: MySQL 5.7中引入了一个新的sys schema,sys是一个MySQL自带的系统库,在安装MySQL 5.7以后的版本,使用mysqld进行初始化时,会自动创建sys库. sys库里面 ...

  7. PHP的循环和函数

    1.循环      1.1for循环 for(初始值;条件;增量){ //循环体 } 1.2while.do-while while(条件){ } ------------------------- ...

  8. 爬虫框架-selenium

    selenium介绍: selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题 selenium本质是通过驱动浏览器,完全模拟 ...

  9. 【hexo+github搭建myblog】bash: npm: command not found 问题,疑似解决!关键词:NPM全局安装路径

    情况:打算用hexo+github搭建个人博客 1. hexo搭建,参考博文如下,非常感谢: Hexo+Github博客搭建完全教程 hexo从零开始到搭建完整 问题: 在最基本的安装步骤 (参考链接 ...

  10. 【React Native】日常踩坑记录_以后将持续更新

    作为一名有理想.有抱负的一代iOS程序员,本着“我头发够多,还能学”的原则,我选择了追随那些大佬的脚步,于2018年开始了React Native. 第一步:找文档.准备安装开发环境: 第二步:一步步 ...