rt,似乎是李超树的部分错了
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf , 1 , 1 << 21 , stdin) , p1 == p2) ? EOF :*p1++)
//char buf[1 << 21], *p1 = buf, *p2 = buf;
inline int read() {
register char c = getchar();
register int x = 0, f = 1;
while(c < '0' || c > '9') {
if (c == '-')
f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = (x << 3) + (x << 1) + c - 48;
c = getchar();
}
return x * f;
}
#define lll long long
const int N = 1e5 + 5;
const lll inf = 123456789123456789ll;
int n , m;
struct node{
int to , next , w;
}e[N << 1];
int head[N] , cnt = 0;
inline void add(int x , int y , int w , int z = 1){
e[++cnt].next = head[x];
e[cnt].to = y;
e[cnt].w = w;
head[x] = cnt;
if(z)
add(y , x , w , 0);
}
int siz[N] , fa[N] , dep[N] , dfn[N] , top[N] , dcnt = 0 , son[N] , rk[N];
lll dis[N];
struct SegTree{
lll k[N << 2] , b[N << 2];
lll mn[N << 2] , ll[N << 2] , rr[N << 2] , mx[N << 2];
void update(int x){
mn[x] = min(mn[x] , min(mn[x << 1] , mn[x << 1 | 1]));
}
void build(int x , int l , int r){
b[x] = mn[x] = inf;
ll[x] = dis[rk[l]];
rr[x] = dis[rk[r]];
if(l == r)
return;
int mid = (l + r) >> 1;
mx[x] = dis[rk[mid]];
build(x << 1 , l , mid);
build(x << 1 | 1 , mid + 1 , r);
}
void modify(int x , int l , int r , int ql , int qr , lll K , lll B){
if(l > qr || r < ql)
return;
if(l >= ql && r <= qr){
lll L = ll[x] , R = rr[x];
lll x0 = k[x] * L + b[x];
lll y0 = k[x] * R + b[x];
lll x1 = K * L + B;
lll y1 = K * R + B;
if(x1 >= x0 && y0 <= y1)
return;
if(x0 >= x1 && y1 <= y0){
k[x] = K;
b[x] = B;
mn[x] = min(mn[x] , min(x1 , y1));
return;
}
int mid = (l + r) >> 1;
lll Mx = mx[x];
double p = 1.0 * (b[x] - B) / (K - k[x]);
if(x0 < x1){
if(p <= (double)Mx){
modify(x << 1 , l , mid , ql , qr , k[x] , b[x]);
k[x] = K;
b[x] = B;
}
else
modify(x << 1 | 1 , mid + 1 , r , ql , qr , K , B);
}
else{
if(p <= (double)Mx)
modify(x << 1 , l , mid , ql , qr , K , B);
else{
modify(x << 1 | 1 , mid + 1 , r , ql , qr , k[x] , b[x]);
k[x] = K;
b[x] = B;
}
}
mn[x] = min(mn[x] , min(x1 , y1));
update(x);
return;
}
int mid = (l + r) >> 1;
modify(x << 1 , l , mid , ql , qr , K , B);
modify(x << 1 | 1 , mid + 1 , r , ql , qr , K , B);
update(x);
}
lll query(int x , int l , int r , int ql , int qr){
if(l > qr || r < ql)
return inf;
if(l >= ql && r <= qr)
return mn[x];
lll res = inf;
if(b[x] != inf){
lll L = max(l , ql);
lll R = min(r , qr);
res = min(k[x] * dis[rk[L]] , k[x] * dis[rk[R]]) + b[x];
}
int mid = (l + r) >> 1;
res = min(res , query(x << 1 , l , mid , ql , qr));
res = min(res , query(x << 1 | 1 , mid + 1 , r , ql , qr));
return res;
}
}Tr;
void dfs1(int u , int f){
siz[u] = 1;
for(int i = head[u]; i; i = e[i].next){
int v = e[i].to;
if(v == f)
continue;
fa[v] = u;
dep[v] = dep[u] + 1;
dis[v] = dis[u] + e[i].w;
dfs1(v , u);
siz[u] += siz[v];
if(siz[v] > siz[son[u]])
son[u] = v;
}
}
void dfs2(int u){
if(u == son[fa[u]])
top[u] = top[fa[u]];
else
top[u] = u;
dfn[u] = ++dcnt;
rk[dcnt] = u;
for(int i = head[u]; i; i = e[i].next){
int v = e[i].to;
if(v == fa[u])
continue;
dfs2(v);
}
}
int lca(int x , int y){
while(top[x] != top[y]){
if(dep[top[x] > dep[top[y]]])
x = fa[top[x]];
else
y = fa[top[y]];
}
if(dep[x] < dep[y])
return x;
else
return y;
}
void modify(int u , int v , lll K , lll B){
while(top[u] != top[v]){
Tr.modify(1 , 1 , n , dfn[top[u]] , dfn[u] , K , B);
u = fa[top[u]];
}
Tr.modify(1 , 1 , n , dfn[v] , dfn[u] , K , B);
}
lll query(int u , int v){
lll res = inf;
while(top[u] != top[v]){
if(dep[top[u]] < dep[top[v]])
swap(u , v);
res = min(res , Tr.query(1 , 1 , n , dfn[top[u]] , dfn[u]));
u = fa[top[u]];
}
if(dep[u] > dep[v])
swap(u , v);
res = min(res , Tr.query(1 , 1 , n , dfn[u] , dfn[v]));
return res;
}
int main(){
scanf("%d%d" , &n , &m);
for(int i = 1; i < n; i++){
int u , v , w;
u = read();
v = read();
w = read();
// scanf("%d%d%d" , &u , &v , &w);
add(u , v , w);
}
dfs1(1 , 0);
dfs2(1);
// cout << "fuck you" << endl;
// for(int i = 1; i <= n; i++){
// cout << siz[i] << " " << son[i] << " " << dep[i] << " " << dis[i] << " " << dfn[i] << " " << rk[i] << endl;;
// }
Tr.build(1 , 1 , n);
while(m--){
int opt;
opt = read();
// scanf("%d" , &opt);
if(opt == 1){
int u , v , K , B;
u = read();
v = read();
K = read();
B = read();
// scanf("%d%d%d%d" , &u , &v , &K , &B);
int LCA = lca(u , v);
modify(u , LCA , -K , dis[u] * K + B);
modify(v , LCA , K , (dis[u] - 2 * dis[LCA]) * K + B);
}
else{
int u , v;
u = read();
v = read();
// scanf("%d%d" , &u , &v);
printf("%lld\n" , query(u , v));
}
}
return 0;
}