Another better difference in the path problem on the tree is to use the information of the root node. .
The form of the question is obviously a linear function, so I thought of maintaining the minimum value of the linear function
The ascending path is: A(d[x]-d[o])+B = -Ad[o]+(B-Ad[x]);
Descent path: A(d[x]+d[o]-2*d[lca])+B = Ad[o]+(B+A(d[o]-2*d[lca]))
Maintain new functions and check them separately when you query. . Because you need interval answers, you need up
No need to down if the mark is permanent
Note:
1. Pay attention to distinguish the original tree and the line segment tree
2. Note that the content of the query is outside and within the scope
3. Pay attention to the order of operations
4. Pay attention to long long
5. Pay attention to the correspondence between d and dui
code:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 100005
#define ll long long
bool cz[N<<2];
int n,m,fu[N],sz[N],zhong[N<<1],tot,hou[N<<1],xia[N],wz[N],top[N],hson[N],cnt,op,lca,x,y,i,dui[N];
ll v[N<<1],d[N],a,b,c,kk[N<<2],bb[N<<2],A,B,ans,minn[N<<2];
void jian(int a,int b,ll c)
{
++tot;hou[tot]=xia[a],xia[a]=tot,zhong[tot]=b,v[tot]=c;
}
void jia(int a,int b,ll c)
{
jian(a,b,c);
jian(b,a,c);
}
void dfs1(int o,int fa,ll dis)
{
sz[o]=1;
d[o]=dis;
fu[o]=fa;
int i,nd;
for(i=xia[o];i!=-1;i=hou[i])
{
nd=zhong[i];
if(nd==fa)continue;
dfs1(nd,o,dis+v[i]);
if(sz[hson[o]]<sz[nd])hson[o]=nd;
sz[o]+=sz[nd];
}
}
void dfs2(int o,int tap)
{
top[o]=tap;
int i,nd;
wz[o]=++cnt;
dui[cnt]=o;
if(hson[o])dfs2(hson[o],tap);
for(i=xia[o];i!=-1;i=hou[i])
{
nd=zhong[i];
if(nd==fu[o]||nd==hson[o])continue;
dfs2(nd,nd);
}
}
void up(int o,ll l,ll mid,ll r)
{
minn[o]= cz[o]? min(kk[o]*d[dui[l]]+bb[o],kk[o]*d[dui[r]]+bb[o]):123456789123456789 ;
minn[o]=min(min(minn[o<<1],minn[o<<1|1]),minn[o]);
}
void gai(int o,int l,int r)
{int mid=(l+r)/2;
if(op==1)//上升
{
if(a<=l&&r<=b)
{
if(cz[o]==0||(kk[o]*d[dui[l]]+bb[o] > -A*d[dui[l]]+(B+A*d[x]) && kk[o]*d[dui[r]]+bb[o] > -A*d[dui[r]]+(B+A*d[x]) ))
{
cz[o]=1;
kk[o]=-A;
bb[o]=B+A*d[x];
minn[o]=min(minn[o],min( -A*d[dui[l]]+(B+A*d[x]),-A*d[dui[r]]+(B+A*d[x])));
return ;
}
if(kk[o]*d[dui[l]]+bb[o] <= -A*d[dui[l]]+(B+A*d[x]) && kk[o]*d[dui[r]]+bb[o] <= -A*d[dui[r]]+(B+A*d[x]) )
{
return ;
}
long double jd=1.0000000*((B+A*d[x])-bb[o])/(1.0000000*(kk[o]+A));
if(jd<=d[dui[mid]])
{
gai(o<<1,l,mid);
if(kk[o]*d[dui[r]]+bb[o] > - A*d[dui[r]]+(B+A*d[x]) )gai(o<<1|1,mid+1,r);
}else
{
gai(o<<1|1,mid+1,r);
if(kk[o]*d[dui[l]]+bb[o] > -A*d[dui[l]]+(B+A*d[x]) )gai(o<<1,l,mid);
}
}else
{
if(a<=mid)gai(o<<1,l,mid);
if(b>mid)gai(o<<1|1,mid+1,r);
}
}
if(op==0)//下降
{
if(a<=l&&r<=b)
{
if(cz[o]==0||(kk[o]*d[dui[l]]+bb[o] > A*d[dui[l]]+(B+A*(d[x]-2*d[lca])) && kk[o]*d[dui[r]]+bb[o] > A*d[dui[r]]+(B+A*(d[x]-2*d[lca])) ))
{
cz[o]=1;
kk[o]=A;
bb[o]=B+A*(d[x]-2*d[lca]);
minn[o]=min(min(A*d[dui[l]]+(B+A*(d[x]-2*d[lca])), A*d[dui[r]]+(B+A*(d[x]-2*d[lca])) ),minn[o]);
return ;
}
if(kk[o]*d[dui[l]]+bb[o] <= A*d[dui[l]]+(B+A*(d[x]-2*d[lca])) && kk[o]*d[dui[r]]+bb[o] <= A*d[dui[r]]+(B+A*(d[x]-2*d[lca])) )
{
return ;
}
long double jd=1.0000000*(B+A*(d[x]-2*d[lca])-bb[o])/(1.0000000*(kk[o]-A));
if(jd<=d[dui[mid]])
{
gai(o<<1,l,mid);
if(kk[o]*d[dui[r]]+bb[o] > A*d[dui[r]]+(B+A*(d[x]-2*d[lca])) )gai(o<<1|1,mid+1,r);
}else
{
gai(o<<1|1,mid+1,r);
if(kk[o]*d[dui[l]]+bb[o] > A*d[dui[l]]+(B+A*(d[x]-2*d[lca])) )gai(o<<1,l,mid);
}
}else
{
if(a<=mid)gai(o<<1,l,mid);
if(b>mid)gai(o<<1|1,mid+1,r);
}
}
if(op==2)
{
if(cz[o])ans=min(min( d[dui[min(1ll*r,b)]]*kk[o]+bb[o], d[dui[max(1ll*l,a)]]*kk[o]+bb[o] ),ans);
if(a<=l&&r<=b)
{
ans=min(ans,minn[o]);
return ;
}
if(a<=mid)
gai(o<<1,l,mid);
if(b>mid)
gai(o<<1|1,mid+1,r);
}
if(l!=r)up(o,l,mid,r);
}
int LCA(int x,int y)
{
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]])swap(x,y);
x=fu[top[x]];
}
if(d[x]>d[y])swap(x,y);
return x;
}
void work(int x,int y)
{ lca=LCA(x,y);
while(top[x]!=top[lca])
{
a=wz[top[x]];b=wz[x];
gai(1,1,n);
x=fu[top[x]];
}
a=wz[lca];b=wz[x];
gai(1,1,n);
if(op==1)op=0;
while(top[y]!=top[lca])
{
a=wz[top[y]];b=wz[y];
gai(1,1,n);
y=fu[top[y]];
}
a=wz[lca];b=wz[y];
gai(1,1,n);
}
void csh(int o,int l,int r)
{
minn[o]=123456789123456789;
if(l==r)return ;
int mid=(l+r)>>1;
csh(o<<1,l,mid);
csh(o<<1|1,mid+1,r);
}
int main()
{
memset(xia,-1,sizeof(xia));
scanf("%d%d",&n,&m);
csh(1,1,n);
for(i=1;i<n;i++)
{
scanf("%lld%lld%lld",&a,&b,&c);
jia(a,b,c);
}
dfs1(1,1,0);
dfs2(1,1);
while(m--)
{
scanf("%d",&op);
if(op==1)
{
scanf("%d%d%lld%lld",&x,&y,&A,&B);
work(x,y);
}else
{
ans=123456789123456789;
scanf("%d%d",&x,&y);
work(x,y);
printf("%lld\n",ans);
}
}
}