题解

#include<stdio.h>
#include<map>
using namespace std;
typedef long long dnt;
map<pair<dnt,dnt>,dnt>  mp1;
map<pair<pair<dnt,dnt>,dnt>,dnt> mp2;
const dnt mod=1e9+7;
const int maxn=200005;
dnt siz[maxn],a[maxn],b[maxn],c[maxn],d[maxn],l[maxn],f[maxn],m;
inline const dnt read(){
    register dnt f=1,x=0;
    register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return f*x;
}
int D(dnt x,dnt u,int v){
    if(x==0) return 0;
    if(mp2[make_pair(make_pair(x,u),v)]) return mp2[make_pair(make_pair(x,u),v)];
    dnt k=siz[a[x]];
    if(u<k&&v<k) return mp2[make_pair(make_pair(x,u),v)]=D(a[x],u,v)%mod;
    else if(u>=k&&v>=k) return mp2[make_pair(make_pair(x,u),v)]=D(b[x],u-k,v-k)%mod;
    else{
       if(u<k) return mp2[make_pair(make_pair(x,u),v)]=((D(a[x],u,c[x])%mod+D(b[x],v-k,d[x])%mod)%mod+l[x]%mod)%mod;
       else return mp2[make_pair(make_pair(x,u),v)]=((D(a[x],v,c[x])%mod+D(b[x],u-k,d[x])%mod)%mod+l[x]%mod)%mod;
    }
}
int A(dnt x,dnt u){
    if(x==0) return 0;
    if(mp1[make_pair(x,u)]) return mp1[make_pair(x,u)];
    dnt k=siz[a[x]];
    if(u<k) return mp1[make_pair(x,u)]=((A(a[x],u)%mod+A(b[x],d[x])%mod)%mod+siz[b[x]]*(l[x]+D(a[x],c[x],u))%mod)%mod;
    else return mp1[make_pair(x,u)]=((A(b[x],u-k)%mod+A(a[x],c[x])%mod)%mod+siz[a[x]]*(l[x]+D(b[x],d[x],u-k))%mod)%mod;
}
int main(){
    siz[0]=1;
    m=read();
    for(register int i=1;i<=m;i++){
        a[i]=read(),b[i]=read(),c[i]=read(),d[i]=read(),l[i]=read();
        siz[i]=siz[a[i]]+siz[b[i]];
        f[i]=((f[a[i]]+f[b[i]])%mod+siz[b[i]]%mod*A(a[i],c[i])%mod)%mod;
        f[i]=(f[i]+siz[a[i]]%mod*A(b[i],d[i])%mod)%mod;
        f[i]=(f[i]+siz[a[i]]%mod*siz[b[i]]%mod*l[i]%mod)%mod;
        printf("%I64d\n",f[i]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值