Loquat
loquat
from CSP-S模拟三
//虽然但是这道题式子出来了就能写出来了
#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
typedef long long ll;
ll m,x,y,u,v,w;
#define ll __int128
map<pair<ll,ll>,ll>dis[310];//记忆化,第一维是树的编号,第二维{,}是起点和终点,表示在第i棵树内a点到b点的距离
struct tree{
ll siz,ans,x,u,y,v,w;//siz是树的大小,ans是路径和,x是两棵树中编号靠前那棵,u是连接x的u号点,y是两棵树中编号靠后的,v是y被连接的v点,w是uv间边权
tree(){
x=y=u=v=w=siz=ans=0;
}
}t[310];
inline ll qry(int tr,ll a,ll b){ //询问两点间距离
if(a==b||tr==0) return 0; //访问到初始的树
if(dis[tr][{a,b}]) return dis[tr][{a,b}];
int xx=t[tr].x,yy=t[tr].y;
//(出锅写法) ll aa=(a<t[xx].siz?xx:yy);
// ll bb=(b<t[xx].siz?xx:yy);
// if(aa==xx&&bb==xx) return dis[tr][{a,b}]=dis[tr][{b,a}]=qry(xx,a,b)%mod;
// if(aa==yy&&bb==yy) return dis[tr][{a,b}]=dis[tr][{b,a}]=qry(yy,a-t[xx].siz,b-t[xx].siz)%mod;
// if(aa==xx&&bb==yy) return dis[tr][{a,b}]=dis[tr][{b,a}]=(qry(xx,a,t[tr].u)+qry(yy,b-t[xx].siz,t[tr].v)+t[tr].w)%mod;
// if(aa==yy&&bb==xx) return dis[tr][{a,b}]=dis[tr][{b,a}]=(qry(xx,b,t[tr].u)+qry(yy,a-t[xx].siz,t[tr].v)+t[tr].w)%mod;
ll aa=(a<t[xx].siz?1:0);ll bb=(b<t[xx].siz?1:0); //起点和终点分别属于哪棵子树
if(aa&&bb) return dis[tr][{a,b}]=dis[tr][{b,a}]=qry(xx,a,b)%mod;//同前子树,缩小范围
if(!aa&&!bb) return dis[tr][{a,b}]=dis[tr][{b,a}]=qry(yy,a-t[xx].siz,b-t[xx].siz)%mod;//同后子树,缩小范围,注意编号要减前树size
if(aa&&!bb) return dis[tr][{a,b}]=dis[tr][{b,a}]=(qry(xx,a,t[tr].u)%mod+qry(yy,b-t[xx].siz,t[tr].v)%mod+t[tr].w%mod)%mod;//一前一后,路径长度=前树点到u的距离+后树点到v的距离+uv间边权,分别递归求解
if(!aa&&bb) return dis[tr][{a,b}]=dis[tr][{b,a}]=(qry(yy,a-t[xx].siz,t[tr].v)%mod+qry(xx,b,t[tr].u)%mod+t[tr].w%mod)%mod;//同上
}
map<ll,ll>di[310];//第i棵树内以j为根,所以节点到j的边权和
inline ll qrysum(int tr,ll q){
if(tr==0) return 0;
if(di[tr][q]) return di[tr][q];
int xx=t[tr].x,yy=t[tr].y;
ll sum=0;
if(q<t[xx].siz){//根节点在前树 ,sum=前树中以q为根的边权和+(q到u的距离+两树间边权w)*后树的大小+后树以v为根边权和
sum=((qry(xx,q,t[tr].u)+t[tr].w)%mod*t[yy].siz%mod)%mod;
sum=(sum+qrysum(yy,t[tr].v)+qrysum(xx,q))%mod;
}
else{//根节点在后树 ,同上
sum=((qry(yy,q-t[xx].siz,t[tr].v)+t[tr].w)%mod*t[xx].siz%mod);
sum=(sum+qrysum(xx,t[tr].u)+qrysum(yy,q-t[xx].siz))%mod;
}
di[tr][q]=sum;
return sum;
}
int main(){
freopen("loquat.in","r",stdin);
freopen("loquat.out","w",stdout);
std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>m;
t[0].siz=1;
for(int i=1;i<=m;i++){
cin>>x>>y>>u>>v>>w;
t[i].siz=t[x].siz+t[y].siz;t[i].x=x;t[i].y=y;
t[i].u=u;t[i].v=v;t[i].w=w;
t[i].ans=(1ll*t[x].siz*qrysum(y,v)%mod+1ll*qrysum(x,u)*t[y].siz%mod+1ll*t[x].siz*t[y].siz%mod*w%mod+1ll*t[x].ans+1ll*t[y].ans)%mod;
cout<<(long long)t[i].ans<<'\n';
}
return 0;
}

浙公网安备 33010602011771号