不是标题党,从11点调到现在了。
自查应该不是线段树元素mn应该全部初始化为INF的问题。
码风丑到离谱,且有压行的大病,见谅。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=100009;
const ll INF=123456789123456789;
inline int read(){
int s=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+ch-'0'; ch=getchar();}
return s*=f;
}
int n,m;
struct edge{int to,w,nxt;} e[N<<1];
int hd[N],tot;
inline void addedge(int u,int v,int w){e[++tot]=(edge){v,w,hd[u]}; hd[u]=tot;}
int p[N],d[N],sz[N],son[N];
int dfn[N],rk[N],timer,top[N];
ll dst[N];
inline void dfs1(int u,int fa){
p[u]=fa; sz[u]=1; d[u]=d[fa]+1;
for(int i=hd[u],v;i;i=e[i].nxt){
v=e[i].to; if(v==fa)continue;
dst[v]=dst[u]+e[i].w;
dfs1(v,u);
sz[u]+=sz[v];
if(sz[son[u]]<sz[v])son[u]=v;
}
}
inline void dfs2(int u,int fa){
rk[dfn[u]=++timer]=u;
top[u]=(u==son[fa])?top[fa]:u;
if(!son[u])return; dfs2(son[u],u);
for(int i=hd[u],v;i;i=e[i].nxt){
v=e[i].to; if(v==fa||v==son[u])continue;
dfs2(v,u);
}
}
struct Line{ll k,b; ll val(int x){return k*dst[rk[x]]+b;}} line[N<<1];
int nL;
struct segment{int l,r,id; ll mn;} tr[N<<2];
inline void build(int u,int l,int r){
tr[u]=(segment){l,r,1,INF};
if(l==r)return;
int mid=(l+r)>>1;
build(u<<1,l,mid); build(u<<1|1,mid+1,r);
}
inline void pushup(int u){tr[u].mn=min(tr[u<<1].mn,tr[u<<1|1].mn);}
inline void upd(int u,int ql,int qr,int id){
if(qr<tr[u].l||tr[u].r<ql)return;
if(ql<=tr[u].l&&tr[u].r<=qr){
if(line[tr[u].id].val(tr[u].l)<=line[id].val(tr[u].l)&&line[tr[u].id].val(tr[u].r)<=line[id].val(tr[u].r))return;
if(line[tr[u].id].val(tr[u].l)>=line[id].val(tr[u].l)&&line[tr[u].id].val(tr[u].r)>=line[id].val(tr[u].r)){tr[u].id=id; tr[u].mn=min(tr[u].mn,min(line[id].val(tr[u].l),line[id].val(tr[u].r))); return;}
int mid=(tr[u].l+tr[u].r)>>1;
if(line[tr[u].id].val(mid)>=line[id].val(mid))swap(tr[u].id,id);
line[tr[u].id].k<line[id].k?upd(u<<1,ql,qr,id):upd(u<<1|1,ql,qr,id);
tr[u].mn=min(tr[u].mn,min(line[id].val(tr[u].l),line[id].val(tr[u].r))); pushup(u);
return;
}
upd(u<<1,ql,qr,id); upd(u<<1|1,ql,qr,id);
pushup(u);
}
inline ll rmnq(int u,int ql,int qr){
if(qr<tr[u].l||tr[u].r<ql)return INF;
if(ql<=tr[u].l&&tr[u].r<=qr)return tr[u].mn;
ll ret=INF;
if(line[tr[u].id].b!=INF)ret=min(line[tr[u].id].val(max(tr[u].l,ql)),line[tr[u].id].val(min(tr[u].r,qr)));
ret=min(ret,min(rmnq(u<<1,ql,qr),rmnq(u<<1|1,ql,qr)));
return ret;
}
inline int lca(int u,int v){
while(top[u]!=top[v])d[top[u]]>d[top[v]]?u=p[top[u]]:v=p[top[v]];
return d[u]>d[v]?v:u;
}
inline void update(int u,int v){
while(top[u]!=top[v]){upd(1,dfn[top[u]],dfn[u],nL); u=p[top[u]];}
upd(1,dfn[v],dfn[u],nL);
}
inline ll query(int u,int v){
ll ret=INF;
while(top[u]!=top[v]){
int&x=(d[top[u]]>d[top[v]]?u:v);
ret=min(ret,rmnq(1,dfn[top[x]],dfn[x]));
x=p[top[x]];
}
if(d[u]>d[v])swap(u,v);
if(u!=v)ret=min(ret,rmnq(1,dfn[u],dfn[v]));
return ret;
}
int main(){
n=read(); m=read();
for(int i=1,u,v,w;i<n;i++){
u=read(); v=read(); w=read();
addedge(u,v,w); addedge(v,u,w);
}
dfs1(1,0); dfs2(1,0);
line[++nL]=(Line){0,INF}; build(1,1,n);
for(int i=1;i<=m;i++){
int op=read(),s=read(),t=read(),l=lca(s,t);
if(op==1){
int a=read(),b=read();
line[++nL]=(Line){-a,a*dst[s]+b}; update(s,l);
line[++nL]=(Line){a,a*(dst[s]-(dst[l]<<1))+b}; update(t,l);
}
else printf("%lld\n",query(s,t));
}
return 0;
}