其他分享
首页 > 其他分享> > CodeForces - 593D Happy Tree Party

CodeForces - 593D Happy Tree Party

作者:互联网

\(\text{Solution}\)

第一眼看见这道题,以为就是 \(\text{CodeForces - 519E A and B and Lecture Rooms}\) 稍微变一变。

然而,\(w_{edge}\le 1e18\)。当场挂掉。

不过,除与乘自有它的好处。我们发现 \(y\le 1e18\),那其实询问只能走 \(\log(1e18)\) 次权值大于 \(1\) 的边(这个数约等于 \(60\))。题目中还有一个重要的条件:\(1<c_i<x_{p_i}\),也就是说一条边的权值为 \(1\) 时就不会再被更改。

我们用冰茶姬将权值为 \(1\) 的一段边缩起来,然后暴力一个个除过去就行了。

\(\text{Code}\)

#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;

const int N=2e5+5;

int n,m,head[N],nxt[N<<1],to[N<<1],cnt,fa[N],f[N][22],dep[N];
ll Val[N<<1],val[N];

ll read() {
	ll x=0,f=1; char s;
	while((s=getchar())>'9'||s<'0') if(s=='-') f=-1;
	while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
	return x*f;
}

void addEdge(int u,int v,ll w) {
	nxt[++cnt]=head[u],to[cnt]=v,head[u]=cnt,Val[cnt]=w;
}

void init() {for(int i=1;i<=n;++i) fa[i]=i;}

int Find(int x) {return x==fa[x]?x:fa[x]=Find(fa[x]);}

void dfs(int u,int ba) {
	dep[u]=dep[ba]+1; f[u][0]=ba;
	for(int i=1;i<=20;++i) f[u][i]=f[f[u][i-1]][i-1];
	for(int i=head[u];i;i=nxt[i]) {
		int v=to[i];
		if(v==ba) continue;
		if(Val[i]==1) fa[v]=Find(u);
		val[v]=Val[i];
		dfs(v,u);
	}
}

int jump(int u,int d) {
	int x=u;
	for(int i=20;i>=0;--i) if(dep[x]-dep[f[u][i]]<=d) u=f[u][i];
	return u;
}

int LCA(int u,int v) {
	if(dep[v]>dep[u]) swap(u,v);
	u=jump(u,dep[u]-dep[v]);
	if(u==v) return u;
	for(int i=20;i>=0;--i)
		if(f[u][i]^f[v][i]) {
			u=f[u][i]; v=f[v][i];
		}
	return f[u][0];
}

int main() {
	int u,v,op,x[N],y[N]; ll w;
	n=read(),m=read();
	for(int i=1;i<n;++i) {
		u=read(),v=read(),w=read();
		addEdge(u,v,w); addEdge(v,u,w);
		x[i]=u,y[i]=v;
	}
	init(); dfs(1,0);
	while(m--) {
		op=read(),u=read();
		if(op==1) {
			v=read(),w=read();
			int lca=LCA(u,v);
			while(dep[u]>dep[lca]&&w) {
				if(val[u]!=1) w/=val[u];
				u=Find(f[u][0]);
			}
			while(dep[v]>dep[lca]&&w) {
				if(val[v]!=1) w/=val[v];
				v=Find(f[v][0]);
			}
			printf("%lld\n",w);
		}
		else {
			w=read();
			v=x[u],u=y[u];
			if(f[u][0]==v) swap(u,v);
			val[v]=w;
			if(w==1) fa[v]=Find(u);
		}
	}
	return 0;
}

标签:593D,return,1e18,val,dep,text,Tree,int,Party
来源: https://www.cnblogs.com/AWhiteWall/p/13532939.html