這道題太噁心了,調了我整整一夜,
結果發現是一個bi——錯誤,多多捂臉
這道題比以前的題多了一個初始化和區間查詢的操做,
主要是區間查詢噁心
由於要區間查詢,因此必須維護區間最低點,
修改和查詢操做被改得面目全非。
咱們要維護的話,必須從現值,子值,新值,具體的很差多說:
看代碼吧:c++
#include<bits/stdc++.h> #define ll long long #define lc x<<1 #define rc x<<1|1 using namespace std; const int N=1e5+6; const ll inf=123456789123456789ll; int n,m,cnt=0,d[N],ff[N],siz[N],top[N],son[N],num[N],head[N]; int t1,t2,opt,s,tt,LCA,dfn=0; ll kk,bb,t3,dis[N],w[N]; struct tree{ll k,b,minx;}t[N<<2]; struct edge{int nxt,to; ll w;}e[N<<1]; inline void add(int u,int v,ll w){e[++cnt].nxt=head[u],e[cnt].to=v,e[cnt].w=w,head[u]=cnt;} inline ll read(){ ll T=0,F=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();} while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar(); return F*T; } void dfs(int x,int fa){ d[x]=d[fa]+1,ff[x]=fa,siz[x]=1; int maxt=0; for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=fa){ dis[e[i].to]=dis[x]+e[i].w,dfs(e[i].to,x),siz[x]+=siz[e[i].to]; if(siz[maxt]<siz[e[i].to]) maxt=e[i].to; } son[x]=maxt; } void dfs2(int x,int topx){ num[x]=++dfn,top[x]=topx,w[dfn]=dis[x]; //cout<<x<<" "<<num[x]<<" "<<top[x]<<" "<<son[x]<<" "<<dis[x]<<endl; if(son[x]) dfs2(son[x],topx); for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=ff[x]&&e[i].to!=son[x]) dfs2(e[i].to,e[i].to); } void build(int l,int r,int x){ t[x].k=0,t[x].b=inf,t[x].minx=inf; if(l==r) return; int mid=l+r>>1; build(l,mid,lc),build(mid+1,r,rc); } inline ll f(tree u,ll v){return u.k*v+u.b;} void update(int l,int r,int p,int q,ll k,ll b,int x){ int mid=l+r>>1; if(p<=l&&r<=q){ if(l==r){if(k*w[l]+b<f(t[x],w[l])) t[x].k=k,t[x].b=b,t[x].minx=f(t[x],w[l]); return;} if(k>t[x].k){ if(k*w[mid]+b<f(t[x],w[mid])) update(mid+1,r,p,q,t[x].k,t[x].b,rc),t[x].k=k,t[x].b=b; else update(l,mid,p,q,k,b,lc); } else{ if(k*w[mid]+b<f(t[x],w[mid])) update(l,mid,p,q,t[x].k,t[x].b,lc),t[x].k=k,t[x].b=b; else update(mid+1,r,p,q,k,b,rc); } t[x].minx=min(t[x].minx,min(f(t[x],w[l]),f(t[x],w[r]))),t[x].minx=min(t[x].minx,min(t[lc].minx,t[rc].minx)); return; } if(p<=mid) update(l,mid,p,q,k,b,lc); if(q>mid) update(mid+1,r,p,q,k,b,rc); t[x].minx=min(t[x].minx,min(t[lc].minx,t[rc].minx)); } ll query(int l,int r,int p,int q,int x){ if(p<=l&&r<=q) return t[x].minx; int mid=l+r>>1; ll ans=inf; if(t[x].b!=inf){ int u=max(l,p),v=min(r,q); ans=min(f(t[x],w[u]),f(t[x],w[v])); } if(p<=mid) ans=min(ans,query(l,mid,p,q,lc)); if(q>mid) ans=min(ans,query(mid+1,r,p,q,rc)); return ans; } void lj_update(int x,int y,ll k,ll b){ while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); update(1,n,num[top[x]],num[x],k,b,1); x=ff[top[x]]; } if(d[x]>d[y]) swap(x,y); update(1,n,num[x],num[y],k,b,1); } ll lj_query(int x,int y){ ll ans=inf; while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); ans=min(ans,query(1,n,num[top[x]],num[x],1)); x=ff[top[x]]; } if(d[x]>d[y]) swap(x,y); ans=min(ans,query(1,n,num[x],num[y],1)); return ans; } int lca(int x,int y){ while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); x=ff[top[x]]; } if(d[x]>d[y]) swap(x,y); return x; } int main(){ n=read(),m=read(); for(int i=1;i<n;++i) t1=read(),t2=read(),t3=read(),add(t1,t2,t3),add(t2,t1,t3); dfs(1,0),dfs2(1,1),build(1,n,1); for(int i=1;i<=m;++i){ opt=read(),s=read(),tt=read(); if(opt==2) printf("%lld\n",lj_query(s,tt)); else kk=read(),bb=read(),LCA=lca(s,tt),lj_update(s,LCA,-kk,kk*dis[s]+bb),lj_update(LCA,tt,kk,kk*(dis[s]-2ll*dis[LCA])+bb); } return 0; }