快来看这个调了半天还5pts的蒟蒻
查看原帖
快来看这个调了半天还5pts的蒟蒻
450902
Maxwell_dcc楼主2022/4/24 16:19

不是标题党,从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;
}
2022/4/24 16:19
加载中...