题目

有\(m+1\)棵树分别为\(T_{0\sim m}\),一开始只有\(T_0\)有一个点,编号为0。

对于每棵树\(T_i\)由T_{a_i}\(的第\)c_i\(个点与\)T_{b_i}\(的第\)d_i\(个点连接后形成。
其中边\)(c_i,d_i)\(的权值为\)l_i\(,若\)T_{a_i}\(有\)s\(个节点,那么原\)T_{b_i}\(部分的编号都要加上\)s\(
问对于任意一棵树,求任意两点间的距离之和。(\)m\leq 60$)


分析

首先\(ans_{T_i}=ans_{T_{a_i}}+ans_{T_{b_i}}+l_i*siz_{T_{a_i}}*siz_{T_{b_i}}+两个子树到其根节点的距离之和\)

前面三个都很好处理,第四个考虑分治,然后用map记忆化答案,保证记录的两个点在同一棵树内

(\(x<y\)表示\(x\)到\(y\)的距离,\(y=0\)表示各点到点\(x\)的距离之和)

首先两点间距离很好求,不同子树内拆开两部分合并,同子树内跳到子树内

然后各点到根节点(选择合并的点)的距离



如果\(x\)在左子树,那么也就是求\(x\)到\(y'\)的距离乘上右子树大小加上\(y'\)和\(x\)内部的贡献

如果\(x\)在右子树,同理,但是注意在右子树的点跳到右子树时编号要减去左子树的大小


代码

#include <cstdio>
#include <cctype>
#include <map>
#define rr register
using namespace std;
typedef long long lll; const int mod=1000000007;
struct rec{int a,b; lll x,y; int w; lll siz;}tre[61];
map<pair<lll,lll>,int>uk[61]; int n,ans[61];
inline lll iut(){
rr lll ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
inline signed mo(int x,int y){return x+y>=mod?x+y-mod:x+y;}
inline signed Get(int k,lll x,lll y){
if (x>y) x^=y,y^=x,x^=y;
if (!k||x==y) return 0;
rr lll A=tre[k].a,B=tre[k].b,sizA=tre[A].siz,sizB=tre[B].siz;
if (y<sizA) return Get(A,x,y);
else if (x>=sizA&&y>=sizA) return Get(B,x-sizA,y-sizA);
else {
rr pair<lll,lll>t=make_pair(x,y);
if (uk[k].find(t)!=uk[k].end()) return uk[k][t];
return uk[k][t]=mo(mo(Get(A,tre[k].x,x),Get(B,tre[k].y,y-sizA)),tre[k].w);
}
}
inline signed calc(int k,lll x){
rr pair<lll,lll>t=make_pair(x,0); if (!k) return 0;
if (uk[k].find(t)!=uk[k].end()) return uk[k][t];
rr int &ans=uk[k][t]; ans=0;
rr lll A=tre[k].a,B=tre[k].b,sizA=tre[A].siz,sizB=tre[B].siz,moA=sizA%mod,moB=sizB%mod;
if (x<sizA) ans=mo(mo(calc(tre[k].a,x),calc(tre[k].b,tre[k].y)),mo(tre[k].w,Get(tre[k].a,tre[k].x,x))*moB%mod);
else ans=mo(mo(calc(tre[k].a,tre[k].x),calc(tre[k].b,x-sizA)),mo(tre[k].w,Get(tre[k].b,tre[k].y,x-sizA))*moA%mod);
return ans;
}
signed main(){
for (rr int Test=iut();Test;--Test){
n=iut(),tre[0].siz=1,ans[0]=0;
for (rr int i=1;i<=n;++i)
tre[i]=(rec){iut(),iut(),iut(),iut(),iut(),0},
tre[i].siz=tre[tre[i].a].siz+tre[tre[i].b].siz;
for (rr int i=0;i<=n;++i) uk[i].clear();
for (rr int i=1;i<=n;++i){
rr lll A=tre[i].a,B=tre[i].b,sizA=tre[A].siz,sizB=tre[B].siz,moA=sizA%mod,moB=sizB%mod;
rr int t1=moA*calc(tre[i].b,tre[i].y)%mod,t2=calc(tre[i].a,tre[i].x)*moB%mod;
ans[i]=mo(mo(mo(ans[A],ans[B]),tre[i].w*moA%mod*moB%mod),mo(t1,t2));
}
for (rr int i=1;i<=n;++i) print(ans[i]),putchar(10);
}
return 0;
}

#分治#JZOJ 4211 送你一颗圣诞树的更多相关文章

  1. JZOJ 4211. 【五校联考1day2】送你一颗圣诞树

    题目 解析 \(Code\) #include<cstdio> #include<map> #include<iostream> #include<cstri ...

  2. Python 送你一棵圣诞树

    Python 送你一棵圣诞树 2019-01-02阅读 8800   今天是圣诞节,先祝大家圣诞快乐!??? 有人要说了,圣诞节是耶稣诞生的日子,我又不信基督教,有啥好庆祝的.这你就有所不知了,Pyt ...

  3. 使用python画一颗圣诞树

    # -*- coding: utf-8 -*- # @Time : 18-12-26 上午9:32 # @Author : Felix Wang import turtle # 定义圣诞树的绿叶函数 ...

  4. 利用js2image把代码压缩成圣诞树

    马上圣诞节了,作为一名程序猿,如何体现自己独特的过节风格,如何在朋友圈发一张专属自己的祝福照片我觉得很有必要,你们说是不是. 谈到圣诞节,话说程序猿和圣诞之间的关系还有这么一个笑话: Q:程序员为什么 ...

  5. 2018.07.20 bzoj2152: 聪聪可可(点分治)

    传送门 本蒟蒻AC的第二道点分治,调了30min" role="presentation" style="position: relative;"&g ...

  6. 树链剖分-点的分治(链的点的个数为k的点对数)

    hdu4760 Cube number on a tree Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65535/65535 ...

  7. 读书笔记-JavaScript面向对象编程(三)

    第7章 浏览器环境 7.1 在HTML页面中引入JavaScript代码 7.2概述BOM与DOM(页面以外事物对象和当前页面对象) 7.3 BOM 7.3.1 window对象再探(所以JavaSc ...

  8. 《Node.js开发实战详解》学习笔记

    <Node.js开发实战详解>学习笔记 ——持续更新中 一.NodeJS设计模式 1 . 单例模式 顾名思义,单例就是保证一个类只有一个实例,实现的方法是,先判断实例是否存在,如果存在则直 ...

  9. hdu4918 Query on the subtree

    树分治,设当前树的分治中心为x,其子树分治中心为y,则设father[y]=x,分治下去则可以得到一颗重心树,而且树的深度是logn. 询问操作(x,d),只需要查询重心树上x到重心树根节点上的节点的 ...

  10. hdu 1710 二叉树的遍历

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1710 大意:给出一个二叉树的前序和中序,求其后序遍历 ps:1.在写链表时,需要写明typedef str ...

随机推荐

  1. [攻防世界][Reverse]xxxorrr

    将目标文件拖入IDA 反汇编main函数 __int64 __fastcall main(int a1, char **a2, char **a3) { int i; // [rsp+Ch] [rbp ...

  2. Unity学习笔记--数据持久化XML文件(1)

    XML相关 Xml是可拓展标记语言,一种文件格式.我们使用xml来完成对数据持久化的存储.等待我们有一程序运行结束之后,将内存中的数据进行保存,(保存在硬盘/服务器)实现对数据的持久化存储. xml文 ...

  3. java图书管理系统界面版本+mysql数据库

    描述: java+mysql数据库实现的图书管理系统,实现了图书添加,图书删除,图书修改,图书查看,图书列表查看等,用户增加,用户删除.用户修改,用户查看等 功能: 图书管理功能:图书添加,图书删除, ...

  4. 一分钟带你了解mySql执行SQL的内部原理

    1.把MySQL当个黑盒子一样执行SQL语句 我们知道执行了insert语句之后,在表里会多出来一条数据:执行了update语句之后,会对表里的数据进行更改:执行了delete语句之后,会把表里的一条 ...

  5. 【Azure 应用服务】App Service / Function App 修改系统时区为中国时区的办法(Azure中所有服务的默认时间都为UTC时间,转换为北京时间需要+8小时)

    问题描述 在Azure的 App Service / Function App 服务中,如果是在Windows系统中,可以通过添加Application Setting来转换为中国时间(WEBSITE ...

  6. 图查询语言 nGQL 简明教程 vol.01 快速入门

    本文旨在让新手快速了解 nGQL,掌握方向,之后可以脚踩在地上借助文档写出任何心中的 NebulaGraph 图查询. 视频 本教程的视频版在B站这里. 准备工作 在正式开始 nGQL 实操之前,记得 ...

  7. ArrayList学习总结

    1.ArrayList简介[1] ArrayList实现了List接口.ArrayList的方法实现和vector相似,只是线程不安全的. ArrayList的 size.isEmpty.get.se ...

  8. Shopee虾皮api接口 搜索商品、评价信息 python数据采集

    iDataRiver平台 https://www.idatariver.com/zh-cn/ 提供开箱即用的Shopee电商数据采集API,供用户按需调用. 接口使用详情请参考Shopee接口文档 接 ...

  9. Go和TinyGo

    Go和TinyGo是两种不同的Go语言编译器,它们之间有以下几点区别: 目标平台: Go:Go语言编译器主要面向通用计算机平台,如Windows.Linux.macOS等. TinyGo:TinyGo ...

  10. (二)Git 学习之基础篇

    一.理论基础 1.1 Git 记录的是什么? Git 和其它版本控制系统(如 SVN)的主要差别在于 Git 对待数据的方式. 1.1.1 SVN 记录差异比较 从概念上来说,SVN 以文件变更列表的 ...