题意

显然树剖套李超树。

考虑怎么算函数值:

设\((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. 第6次作业--static关键字、对象

    题目1:编写一个类Computer,类中含有一个求n的阶乘的方法.将该类打包,并在另一包中的Java文件App.java中引入包,在主类中定义Computer类的对象,调用求n的阶乘的方法(n值由参数 ...

  2. A1071 Speech Patterns (25 分)

    一.技术总结 开始拿到这道题目时,思考的是我该如何区分它们每一个单词,不知道这里还是要学习得知在cctype头文件中有一个函数用于查看是否为0~9.a~z.A~Z,就是isalnum(),又因为题目中 ...

  3. .NET Core NuGet 多项目套餐打包的正确姿势

    NuGet 默认只支持一个菜一个菜打包,不支持套餐打包.当对一个 csproj 项目进行 nuget 打包时(比如使用 dotnet pack 命令),只会将当前项目 build 出来的 dll 程序 ...

  4. Python开发GUI实战:图片转换素描画工具!

    奋斗没有终点 好好学习72变,因为将来 没有人能替你阻挡81难 . 生如蝼蚁,当有鸿鹄之志: 命如纸薄,应有不屈之心 . ​ 今天被这句话触动了,所以开篇分享给大家.鸡汤有毒,但有时大家却靠它激励自己 ...

  5. CF 704 D. Captain America

    CF 704 D. Captain America 题目链接 题目大意:给出\(n\)个点的坐标,你要将每个点染成红色或者蓝色.染一个红色要付出\(r\)的代价,染一个蓝色要付出\(b\)的代价.有\ ...

  6. Samba基础配置

    本文环境:CentOS 7 简介 在UNIX-like之间共享文件系统主要是通过NFS实现的,而Windows之间共享文件系统主要是通过基于NetBIOS的网上邻居实现的,1984年Andrew Tr ...

  7. Saiku使用iframe嵌入页面访问地址配置化(二十八)--DWR的基本使用

    Saiku使用iframe嵌入页面使用时ip与端口配置化(二十八)--DWR的基本使用 DWR(Direct Web Remoting)是一个用于改善web页面与Java类交互的远程服务器端Ajax开 ...

  8. VRF--虚拟路由表

    VRF Virtual routing forwarding,虚拟路由转发表,简称VPN.他能在两个site之间建立两个不用的路由表,相互隔离,把每台交换机逻辑上分成多台虚拟交换机,即多VPN路由转发 ...

  9. ASP.NET Core使用Nacos作为配置中心的多环境问题

    前言 双11那天离职后,这段时间都待在家里,看看书,写写代码,逛逛招聘网站 周一去Gworld面试的时候,有听到面试官说他们用到了配置中心Apollo,聊下来,听他的意思,大概是处理了多环境这个比较方 ...

  10. 一次业务网关用ASP.NET Core 2.1重构的小结

    目录 前言 统一鉴权 服务限流 路由转发 参数重组 链路跟踪 熔断降级 服务计次 业务指标监控 日志记录 迭代更新 总结 前言 对于API网关,业界貌似对它进行下划分,有下面几个分类/场景. 面向We ...