每当 Bob 进行操作,输出一行一个数,表示他能够选择的最小的数字
n≤100000,m≤100000,∣a∣≤10000,0<=w,|b|<=10^9
鸣谢Menci上传
#include #include #include #include #include #include #include #include #include #include #include #include using namespace std; const int maxn = 1E5 + 10; const int T = 20; typedef long long LL; const LL Inf = 123456789123456789; typedef double DB; struct E{ int to,w; E (int _to = 0,int _w = 0) {to = _to; w = _w;} }; int n,m,cnt,Root,Lca,I,fa[maxn][20],len[maxn],Nex[maxn],L[maxn] ,First[maxn],pos[maxn],siz[maxn],root[maxn],lc[maxn*T],rc[maxn*T]; LL ans,Min[maxn*T],Light[maxn],k[maxn*T],b[maxn*T],dis2[maxn],dis[maxn]; bool Huge[maxn]; vector v[maxn]; vector Road[maxn]; int New() {++cnt; k[cnt] = 0; b[cnt] = Min[cnt] = Inf; return cnt;} int Getlc(int o) {return lc[o]?lc[o]:lc[o] = New();} int Getrc(int o) {return rc[o]?rc[o]:rc[o] = New();} void dfs(int x,int from) { Light[x] = Inf; siz[x] = 1; int Max = 0,po; for (int i = 1; i < 20; i++) fa[x][i] = fa[fa[x][i-1]][i-1]; for (int i = 0; i < v[x].size(); i++) { int to = v[x][i].to; if (to == from) continue; fa[to][0] = x; dis[to] = dis[x] + 1LL*v[x][i].w; L[to] = L[x] + 1; dfs(to,x); siz[x] += siz[to]; if (siz[to] > Max) Max = siz[to],po = to; } if (siz[x] > 1) Huge[po] = 1,Nex[x] = po; } void dfs2(int x,int from,int Len) { if (siz[x] == 1) { if (Huge[x]) { len[x] = Len + 1; First[x] = x; root[x] = New(); pos[x] = 1; k[cnt] = 0; b[cnt] = Inf; dis2[x] = 0; Road[x].push_back(0); Road[x].push_back(x); } return; } Len = Huge[x]?++Len:0; for (int i = 0; i < v[x].size(); i++) { int to = v[x][i].to; if (to == from) continue; dfs2(to,x,Len); } if (Huge[x]) { root[x] = root[Nex[x]]; len[x] = len[Nex[x]]; First[x] = First[Nex[x]]; pos[x] = pos[Nex[x]] + 1; dis2[x] = dis2[Nex[x]] + dis[Nex[x]] - dis[x]; Road[First[x]].push_back(x); } } void pushdown(int o,int belong,int l,int r,LL K,LL B) { int numl = Road[belong][l]; int numr = Road[belong][r]; LL A1 = dis2[numl]*K + B,A2 = dis2[numl]*k[o] + b[o]; LL B1 = dis2[numr]*K + B,B2 = dis2[numr]*k[o] + b[o]; Min[o] = min(Min[o],min(A1,B1)); if (A1 < A2 && B1 < B2) { Min[o] = min(Min[o],min(A1,B1)); k[o] = K; b[o] = B; return; } if (A1 >= A2 && B1 >= B2) return; DB x = (DB)(b[o] - B)/(DB)(K - k[o]); int Mid = Road[belong][(l+r)>>1]; LL mid = dis2[Mid]; Mid = pos[Mid]; if (x <= mid) { if (A1 > A2) pushdown(Getlc(o),belong,l,Mid,k[o],b[o]),k[o] = K,b[o] = B; else pushdown(Getlc(o),belong,l,Mid,K,B); } else { if (A1 > A2) pushdown(Getrc(o),belong,Mid+1,r,K,B); else pushdown(Getrc(o),belong,Mid+1,r,k[o],b[o]),k[o] = K,b[o] = B; } Min[o] = min(Min[o],min(Min[Getlc(o)],Min[Getrc(o)])); } void modify(int o,int belong,int l,int r,int ml,int mr,LL K,LL B) { if (ml <= l && r <= mr) {pushdown(o,belong,l,r,K,B); return;} int mid = (l + r) >> 1; if (ml <= mid) modify(Getlc(o),belong,l,mid,ml,mr,K,B); if (mr > mid) modify(Getrc(o),belong,mid+1,r,ml,mr,K,B); Min[o] = min(Min[o],min(Min[Getlc(o)],Min[Getrc(o)])); } int Quickfa(int x,int y) { for (int num = 0; y; y >>= 1,++num) if (y & 1) x = fa[x][num]; return x; } void Modify1(int x,LL K,LL B) { LL Dis = 0; for (; x != Lca; Dis += (dis[x] - dis[fa[x][0]]),x = fa[x][0]) { if (!Huge[x]) Light[x] = min(Light[x],K*Dis + B); else { if (pos[x] == 1) { if (L[x] - (len[x] - pos[x]) > L[Lca]) { modify(root[x],First[x],1,len[x],pos[x],len[x],K,B+Dis*K); Dis += dis[x]; x = Quickfa(x,len[x] - pos[x]); Dis -= dis[x]; } else { modify(root[x],First[x],1,len[x],pos[x],pos[Lca]-1,K,B+Dis*K); return; } } else { if (L[x] - (len[x] - pos[x]) > L[Lca]) { modify(root[x],First[x],1,len[x],pos[x],len[x],K,B+(Dis-dis2[x])*K); Dis += dis[x]; x = Quickfa(x,len[x] - pos[x]); Dis -= dis[x]; } else { modify(root[x],First[x],1,len[x],pos[x],pos[Lca]-1,K,B+(Dis-dis2[x])*K); return; } } } } } void Modify2(int x,LL K,LL B,LL Dis) { Dis += (dis[x] - dis[Lca]); for (; x != Lca; Dis -= (dis[x] - dis[fa[x][0]]),x = fa[x][0]) { if (!Huge[x]) Light[x] = min(Light[x],K*Dis + B); else { if (pos[x] == 1) { if (L[x] - (len[x] - pos[x]) > L[Lca]) { modify(root[x],First[x],1,len[x],pos[x],len[x],-K,B+Dis*K); Dis -= dis[x]; x = Quickfa(x,len[x] - pos[x]); Dis += dis[x]; } else { modify(root[x],First[x],1,len[x],pos[x],pos[Lca]-1,-K,B+Dis*K); return; } } else { if (L[x] - (len[x] - pos[x]) > L[Lca]) { modify(root[x],First[x],1,len[x],pos[x],len[x],-K,B+(Dis+dis2[x])*K); Dis -= dis[x]; x = Quickfa(x,len[x] - pos[x]); Dis += dis[x]; } else { modify(root[x],First[x],1,len[x],pos[x],pos[Lca]-1,-K,B+(Dis+dis2[x])*K); return; } } } } } LL query(int o,int belong,int l,int r,int ql,int qr) { LL QL = Road[belong][max(ql,l)]; QL = dis2[QL]; LL QR = Road[belong][min(qr,r)]; QR = dis2[QR]; LL A1 = QL*k[o] + b[o]; LL B1 = QR*k[o] + b[o]; if (ql <= l && r <= qr) return min(Min[o],min(A1,B1)); int mid = (l + r) >> 1; LL ret = Inf; if (ql <= mid) ret = min(ret,query(Getlc(o),belong,l,mid,ql,qr)); if (qr > mid) ret = min(ret,query(Getrc(o),belong,mid+1,r,ql,qr)); return min(ret,min(A1,B1)); } void Query(int x) { for (; x != Lca; x = fa[x][0]) { if (!Huge[x]) ans = min(ans,Light[x]); else { if (L[x] - (len[x] - pos[x]) > L[Lca]) { ans = min(ans,query(root[x],First[x],1,len[x],pos[x],len[x])); x = Quickfa(x,len[x] - pos[x]); } else { ans = min(ans,query(root[x],First[x],1,len[x],pos[x],pos[Lca]-1)); return; } } } } int getint() { char ch = getchar(); int ret = 0,multi = 1; while (ch < '0' || '9' < ch) { if (ch == '-') multi = -1; ch = getchar(); } while ('0' <= ch && ch <= '9') ret = ret*10 + ch - '0',ch = getchar(); return ret*multi; } int LCA(int p,int q) { if (L[p] < L[q]) swap(p,q); int Log; for (Log = 0; L[p] - (1<= 1; Log++); --Log; for (int j = Log; j >= 0; j--) if (L[p] - (1<= L[q]) p = fa[p][j]; if (p == q) return p; for (int j = Log; j >= 0; j--) if (fa[p][j] != fa[q][j]) p = fa[p][j],q = fa[q][j]; return fa[p][0]; } int main() { #ifdef DMC //freopen("DMC.txt","r",stdin); freopen("game20.in","r",stdin); freopen("test.txt","w",stdout); #endif n = getint(); m = getint(); for (int i = 1; i < n; i++) { int x = getint(),y = getint(),z = getint(); v[x].push_back(E(y,z)); v[y].push_back(E(x,z)); } Root = n/2; L[Root] = 1; dfs(Root,0); dfs2(Root,0,0); for (I = 1; I <= m; I++) { int typ = getint(),s = getint(),t = getint(); Lca = LCA(s,t); if (typ == 1) { LL K = getint(),B = getint(); if (Lca != s) Modify1(s,K,B); if (!Huge[Lca]) Light[Lca] = min(Light[Lca],(dis[s] - dis[Lca])*K + B); else { DB NewB = (dis[s] - dis[Lca] - dis2[Lca])*K+B; modify(root[Lca],First[Lca],1,len[Lca],pos[Lca],pos[Lca],K,NewB); } if (Lca != t) Modify2(t,K,B,dis[s] - dis[Lca]); } else { ans = Inf; if (s != Lca) Query(s); if (t != Lca) Query(t); if (!Huge[Lca]) ans = min(ans,Light[Lca]); else ans = min(ans,query(root[Lca],First[Lca],1,len[Lca],pos[Lca],pos[Lca])); printf("%lld\n",ans); } } return 0; }