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;
}
posted @ 2019-10-12 17:24  lsoi_ljk123  阅读(166)  评论(0编辑  收藏  举报