zoukankan      html  css  js  c++  java
  • CodeForces

    ( ext{Description})

    传送门

    ( ext{Solution})

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

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

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

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

    ( ext{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
    ",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;
    }
    
  • 相关阅读:
    u-boot 2011.09 调用kernel 的流程
    Delphi repeat Until 运用
    clientdataset的使用
    类型TTreeView.items.add 与 TTreeView.items.addchild有何区别?(10分)
    delphi中nil、null、UnAssigned区别
    操作TreeView(咏南工作室)
    delphi7 treeview + 数据库 实现动态节点维护
    Delphi Try Except 实例
    Delphi 中自定义异常及异常处理的一般方法
    Delphi中的异常处理(10种异常来源、处理、精确处理)
  • 原文地址:https://www.cnblogs.com/AWhiteWall/p/13532939.html
Copyright © 2011-2022 走看看