记录编号 390030 评测结果 AAWWWWWWWWWWWWWWWWWW
题目名称 [SDOI 2016 Round1] 游戏 最终得分 10
用户昵称 GravatarFoolMike 是否通过 未通过
代码语言 C++ 运行时间 30.895 s
提交时间 2017-04-01 15:40:30 内存使用 233.00 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int N=1e6+10;
const ll inf=123456789123456789ll;
struct edge{int f,t,l;}w[N];
int n,m,next[N],head[N];
void add(int f,int t,int l){
	static int cnt=0;
	w[++cnt]=(edge){f,t,l};
	next[cnt]=head[f];
	head[f]=cnt;
}
int fa[N],dfn[N],link[N],size[N],big[N];
ll h[N],dep[N];
void dfs(int x){
	size[x]=1;
	for (int i=head[x];i;i=next[i])
	if (!fa[w[i].t]){
		int v=w[i].t;
		fa[v]=x;
		h[v]=h[x]+w[i].l;
		dfs(v);
		size[x]+=size[v];
		if (size[v]>size[big[x]]) big[x]=v;
	}
}
void po(int x){
	static int cnt=0;
	dfn[x]=++cnt;
	link[x]=(cnt==dfn[fa[x]]+1?link[fa[x]]:x);
	if (!big[x]) return;
	po(big[x]);
	for (int i=head[x];i;i=next[i])
		if (w[i].t!=big[x]&&w[i].t!=fa[x]) po(w[i].t); 
}
int lca(int x,int y){
	for (;link[x]!=link[y];x=fa[link[x]])
		if (dfn[link[x]]<dfn[link[y]]) swap(x,y);
	return dfn[x]<dfn[y]?x:y;
}
struct pt{
	ll x,y;
	pt(ll X=0,ll Y=0){x=X;y=Y;}
	pt operator - (const pt a)const{return pt(x-a.x,y-a.y);}
	ll operator * (const pt a)const{return x*a.y-y*a.x;}
};
struct half_plane{
private:
	vector<pt> q;
	int tl;
	bool check(pt &x,pt &y,pt &z){
		return (y-x)*(z-x)>0;
	}
	void insert(pt &x){
		for (;tl>=0&&check(q[tl-1],q[tl],x);q.pop_back(),tl--);
		q.push_back(x);tl++;
	}
public:
	void init(){q.clear();tl=-1;}
	void ins(pt x){
		if (tl>0&&q[tl].x==x.x){
			if (q[tl].y>x.y) q.pop_back(),tl--,insert(x);
			return;
		}
		insert(x);
	}
	ll query(ll x){
		if (tl<0) return inf;
		int l=0,r=tl;
		while (l^r){
			int mid=(l+r)>>1;
			if (x*(q[mid].x-q[mid+1].x)<q[mid+1].y-q[mid].y) r=mid;else l=mid+1;
		}
		return x*q[l].x+q[l].y;
	}
};
int L,R;pt v;
struct segment_tree{
	half_plane a[N];
	ll Min[N];
	segment_tree(){
		for (int i=1;i<N;i++)
			a[i].init(),Min[i]=inf;
	}
	#define lc x<<1
	#define rc x<<1|1
	void clear(int x,int l,int r){
		a[x].init();Min[x]=inf;
		if (l>=L&&r<=R) return;
		int mid=(l+r)>>1;
		if (L<=mid) clear(lc,l,mid);
		if (R>mid) clear(rc,mid+1,r);
	}
	void add(int x,int l,int r){
		if (l>=L&&r<=R){
			a[x].ins(v);
			Min[x]=min(Min[x],a[x].query(dep[l]));
			Min[x]=min(Min[x],a[x].query(dep[r]));
			return;
		}
		int mid=(l+r)>>1;
		if (L<=mid) add(lc,l,mid);
		if (R>mid) add(rc,mid+1,r);
		Min[x]=min(Min[lc],Min[rc]);
	}
	ll query(int x,int l,int r){
		if (l>=L&&r<=R) return Min[x];
		int mid=(l+r)>>1;
		ll ans=min(a[x].query(dep[min(r,R)]),a[x].query(dep[max(l,L)]));
		if (L<=mid) ans=min(ans,query(lc,l,mid));
		if (R>mid) ans=min(ans,query(rc,mid+1,r));
		return ans;
	}
}T;
const int M=4e6+10;
ll ans[M];
struct opt{int tp,l,r;ll a,b;}Q[M];int id;
void modify(int s,int t){
	ll a,b;
	scanf("%lld%lld",&a,&b);
	int LCA=lca(s,t);
	b+=a*h[s];
	for (;link[s]!=link[LCA];s=fa[link[s]])
		Q[++id]=(opt){1,dfn[link[s]],dfn[s],-a,b};
	Q[++id]=(opt){1,dfn[LCA],dfn[s],-a,b};
	b-=2*a*h[LCA];
	for (;link[t]!=link[LCA];t=fa[link[t]])
		Q[++id]=(opt){1,dfn[link[t]],dfn[t],a,b};
	Q[++id]=(opt){1,dfn[LCA],dfn[t],a,b};
}
ll query(int x,int y){
	ll ans=inf;
	for (;link[x]!=link[y];x=fa[link[x]]){
		if (dfn[link[x]]<dfn[link[y]]) swap(x,y);
		L=dfn[link[x]];R=dfn[x];
		ans=min(ans,T.query(1,1,n));
	}
	if (dfn[x]>dfn[y]) swap(x,y);
	L=dfn[x];R=dfn[y];
	return min(ans,T.query(1,1,n));
}
int q[M];
void cdq(int l,int r){
	if (l==r) return;
	int mid=(l+r)>>1;
	cdq(l,mid);cdq(mid+1,r);
	for (int i=l;i<=mid;i++){
		opt &now=Q[q[i]];
		if (now.tp==1){
			L=now.l;R=now.r;v=pt(now.a,now.b);
			T.add(1,1,n);
		}
	}
	for (int i=mid+1;i<=r;i++)
		if (!Q[i].tp) ans[i]=min(ans[i],query(Q[i].l,Q[i].r));
	for (int i=l;i<=mid;i++){
		opt &now=Q[q[i]];
		if (now.tp==1) L=now.l,R=now.r,T.clear(1,1,n);
	}
	static int a[N];
	int i=l,j=mid+1,p=l;
	while (i<=mid&&j<=r) a[p++]=Q[q[i]].a>Q[q[j]].a?q[i++]:q[j++];
	for (;i<=mid;a[p++]=q[i++]);
	for (;j<=r;a[p++]=q[j++]);
	for (i=l;i<=r;i++) q[i]=a[i];
}
int main()
{
	freopen("menci_game.in","r",stdin);
	freopen("menci_game.out","w",stdout);
	scanf("%d%d",&n,&m);
	for (int i=1;i<n;i++){
		int u,v,l;
		scanf("%d%d%d",&u,&v,&l);
		add(u,v,l);add(v,u,l);
	}
	fa[1]=1;dfs(1);po(1);
	for (int i=1;i<=n;i++) dep[dfn[i]]=h[i];
	while (m--){
		int tp,x,y;
		scanf("%d%d%d",&tp,&x,&y);
		if (tp==1) modify(x,y);else Q[++id]=(opt){0,x,y,0ll,0ll};
	}
	for (int i=1;i<=id;i++) q[i]=i,ans[i]=inf;
	//for (int i=1;i<=id;i++)
	//	printf("%d %d->%d a=%lld b=%lld\n",Q[i].tp,Q[i].l,Q[i].r,Q[i].a,Q[i].b);
	cdq(1,id);
	for (int i=1;i<=id;i++)
		if (!Q[i].tp) printf("%lld\n",ans[i]);
	return 0;
}