CF593D Happy Tree Party题解
CF593D Happy Tree Party题解
水题树剖,维护乘积和单点修改的线段树
但会爆long long,用double 神奇维护???
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lc x<<1
#define rc x<<1|1
const int N=2e5+6;
const double maxx=1e18;
int n,m,opt,t1,t2,cnt=0,dfn=0,d[N],f[N],id[N],son[N],siz[N],num[N],top[N],head[N];
ll t3,v[N],o[N];
double tt,w[N<<2],lazy[N<<2];
struct edge{int nxt,to,p; ll w;}e[N<<1];
inline void add(int u,int v,int p,ll w){e[++cnt].nxt=head[u],e[cnt].to=v,e[cnt].p=p,e[cnt].w=w,head[u]=cnt;}
inline double mul(double x,double y){return (!x&&maxx/x>=y)?maxx:x*y;}
inline ll read(){
ll T=0,F=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
return F*T;
}
void dfs(int x,int fa){
siz[x]=1,d[x]=d[fa]+1,f[x]=fa; int maxt=0;
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=fa){
id[e[i].p]=e[i].to,dfs(e[i].to,x),siz[x]+=siz[e[i].to];
if(siz[maxt]<siz[e[i].to]) maxt=e[i].to,o[x]=e[i].w;
}
son[x]=maxt;
}
void dfs2(int x,int topx,ll ww){
num[x]=++dfn,top[x]=topx,v[dfn]=ww;
if(son[x]) dfs2(son[x],topx,o[x]);
for(int i=head[x];i;i=e[i].nxt) if(e[i].to!=f[x]&&e[i].to!=son[x]) dfs2(e[i].to,e[i].to,e[i].w);
}
void build(int l,int r,int x){
if(l==r){w[x]=v[l]; return;}
int mid=l+r>>1;
build(l,mid,lc),build(mid+1,r,rc);
w[x]=mul(w[lc],w[rc]);
}
void update(int l,int r,int p,int x,ll y){
if(l==r){w[x]=y; return;}
int mid=l+r>>1;
if(p<=mid) update(l,mid,p,lc,y);
else update(mid+1,r,p,rc,y);
w[x]=mul(w[lc],w[rc]);
}
double query(int l,int r,int p,int q,int x){
if(p<=l&&r<=q) return w[x];
int mid=l+r>>1; double ans=1;
if(p<=mid) ans=query(l,mid,p,q,lc);
if(q>mid) ans=mul(ans,query(mid+1,r,p,q,rc));
return ans;
}
double lj_query(int x,int y){
double ans=1;
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]]) swap(x,y);
ans=mul(ans,query(1,n,num[top[x]],num[x],1));
x=f[top[x]];
}
if(d[x]>d[y]) swap(x,y);
if(x!=y) ans=mul(ans,query(1,n,num[x]+1,num[y],1));
return ans;
}
int main(){
n=read(),m=read();
for(int i=1;i<n;++i) t1=read(),t2=read(),t3=read(),add(t1,t2,i,t3),add(t2,t1,i,t3);
dfs(1,0),dfs2(1,1,1),build(1,n,1);
for(int i=1;i<=m;++i){
opt=read(),t1=read();
if(opt==1){
t2=read(),t3=read(),tt=lj_query(t1,t2);
if(fabs(tt)<1e-4) printf("0\n");
else printf("%lld\n",(ll)(t3/tt));
}
else t3=read(),update(1,n,num[id[t1]],1,t3);
}
return 0;
}