分析:好神的一道题啊.对每棵树建个图跑一下floyd可以有40分,想要打出正解就得对树有比较深的认识了.

每次新生成一棵树都是由两棵树i,j拼成的,答案为原来两棵树的答案和+i中每个点到j中每个点的距离和.显然这个距离和不能直接算,涉及到求整体的值,通常考虑每条边的贡献.设i,j两棵树的连接点为p,q,边长为l.l对答案的贡献是i的点数*j的点数*l.i中每个点要走到j里面,必须要先走到p上,i中的每个点对它走过的路径的贡献是j的点数*路径的边权,因为每条路径都被若干个点经过,所以算出i中所有点到p的距离和乘上j的点数就是i中的边对答案的贡献.j中所有边对答案的贡献也是这样算的.

那么怎么求树i中所有点到t的距离和呢?还是可以把树i拆分成两棵子树x,y.如果p在i的左子树中,那么就是连接点p到t的距离加上连接x,y的边的长度l的和乘上y中的点数加上y中所有点到q的距离和加上x中所有点到t的距离和.这实际上就相当于拆成了3部分:1是x里面的所有点到t去,2是y中的所有点到q去,3是y中所有点聚集到q后一起到t.如果p在i的右子树中,做法类似,递归地算下去.

那么怎么求p到t的距离呢?还是分两个点所在的树来讨论.如果p,t在同一子树,就在同一子树内递归算,如果在不同子树就先到连接点,然后再走过去,和之前的做法差不多.

因为求得的东西要经常被用到,所以需要记录状态的,可是m≤60,点的个数可能多达2^60个,这该怎么记录......其实需要记录的只有连接点的状态,但是连接点的编号可能很大,也会爆空间,一个很神的技巧就是在map中保存状态orz.开long long就能存下了.

丧心病狂的一道题,求两棵树任意两点之间的距离和的做法在树形dp中比较常见,需要记一下.黑科技map可以记录不多,但是表示起来很大的状态.

#include <map>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; typedef long long ll; const int mod = 1e9 + ; struct node
{
ll p, p1, p2;
node(){}
node(ll a, ll b, ll c)
{
p = a;
if (b < c)
{
p1 = b;
p2 = c;
}
else
{
p1 = c;
p2 = b;
}
}
bool operator < (const node & a) const {
if (p != a.p)
return p < a.p;
if (p1 != a.p1)
return p1 < a.p1;
return p2 < a.p2;
}
}; int n;
ll id1[], id2[], num1[], num2[], l[], sizee[];
ll ans[]; map <pair< ll, ll > , ll > m;
map <node, ll> m2; ll solve2(ll p, ll p1, ll p2)
{
if (!p)
return ;
if (p1 == p2)
return ;
node temp = node(p, p1, p2);
if (m2.count(temp))
return m2[temp];
if (p1 < sizee[id1[p]])
{
if (p2 < sizee[id1[p]])
m2[temp] = solve2(id1[p], p1, p2);
else
m2[temp] = (solve2(id1[p], num1[p], p1) + solve2(id2[p], num2[p], p2 - sizee[id1[p]]) + l[p]) % mod;
}
else
{
if (p2 < sizee[id1[p]])
m2[temp] = (solve2(id1[p], num1[p], p2) + solve2(id2[p], num2[p], p1 - sizee[id1[p]]) + l[p]) % mod;
else
m2[temp] = solve2(id2[p], p1 - sizee[id1[p]], p2 - sizee[id1[p]]);
}
return m2[temp];
} ll solve(ll p, ll n)
{
if (p == )
return ;
pair <ll, ll> t = make_pair(p, n);
if (m.count(t))
return m[t];
if (n < sizee[id1[p]])
{
ll temp1 = (solve2(id1[p], num1[p], n) + l[p]) % mod;
ll temp2 = temp1 * (sizee[id2[p]] % mod) % mod;
ll temp3 = (solve(id2[p], num2[p]) + solve(id1[p], n)) % mod;
m[t] = (temp2 + temp3) % mod;
}
else
{
ll temp1 = (solve2(id2[p], num2[p], n - sizee[id1[p]]) + l[p]) % mod;
ll temp2 = temp1 * (sizee[id1[p]] % mod) % mod;
ll temp3 = (solve(id1[p], num1[p]) + solve(id2[p], n - sizee[id1[p]])) % mod;
m[t] = (temp2 + temp3) % mod;
}
return m[t];
} int main()
{
scanf("%d", &n);
for (int i = ; i <= n; i++)
scanf("%lld%lld%lld%lld%lld", &id1[i], &id2[i], &num1[i], &num2[i], &l[i]);
sizee[] = ;
for (int i = ; i <= n; i++)
sizee[i] = sizee[id1[i]] + sizee[id2[i]];
for (int i = ; i <= n; i++)
{
ll temp1 = solve(id1[i], num1[i]) * (sizee[id2[i]] % mod) % mod;
ll temp2 = (sizee[id1[i]] % mod )* (sizee[id2[i]] % mod) % mod * l[i] % mod;
ll temp3 = solve(id2[i], num2[i]) * (sizee[id1[i]] % mod) % mod;
ans[i] = (((((((temp1 + temp2) % mod) + temp3) % mod) + ans[id1[i]]) % mod) + ans[id2[i]]) % mod;
}
for (int i = ; i <= n; i++)
printf("%lld\n", ans[i]);
return ;
}

noip模拟赛 洗衣的更多相关文章

  1. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  2. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  3. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  4. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  5. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  6. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  7. 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...

  8. CH Round #58 - OrzCC杯noip模拟赛day2

    A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...

  9. CH Round #52 - Thinking Bear #1 (NOIP模拟赛)

    A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...

随机推荐

  1. ionic2.1.0 --beta3版本新建页面做弹框时遇到的问题

    新建的页面需要在app.module.ts文件中定义.不然制作页面弹出效果是会报错.

  2. c++ memset函数

    函数名称:memset 函数所需头文件:#include<cstring> 函数作用:内存赋值函数,用来给某一块内存空间进行赋值的. 函数结构:memset(变量,一个数字,一个数字)  ...

  3. struct结构的一些内容

    srtuct结构的定义: 访问修饰符 struct  结构名{ //方法体 } 结构定义的特点: 1.结构中可以有字段(属性),也可以有方法 2.定义时,结构的字段不能被赋初值 3.结构和类一样都有默 ...

  4. 喜欢Swift编程语言的人主要是初学者?

    一早一起来,朋友圈除了被苹果发布会刷屏外,还漫天散布着一条类似的招聘消息:“招聘iOS程序员,要求拥有5年的Swift开发经验,有狼性,待遇月薪20K+,专车接送.” 随后身边的朋友很快就开始调侃:& ...

  5. Java使用 POI 操作Excel

    Java中常见的用来操作 Excel 的方式有2种:JXL和POI.JXL只能对 Excel进行操作,且只支持到 Excel 95-2000的版本.而POI是Apache 的开源项目,由Java编写的 ...

  6. 6.12---知道参数的重要性------插入数据-删除数据-修改数据注意Map

    ---------------

  7. mac当你有多个版本的命令存在是怎么使用最新版本

    例如你安装了一个最新的git.然而系统中由于xcode等自带的git的存在.使得/usr/bin/git 是xcode的版本. 只需要再 ~/.bash_profile 中添加一行优先path即可 e ...

  8. React 篇 Search Bar and content Table

    我们要构建一个模块,其中包含一个内容显示的表格,然后上面有一个提供Search的栏位,并对Search中输入栏进行监听,当有改变的时候,触发Search然后对内容表中的内容进行过滤. Demo Lin ...

  9. Tomcat环境的搭建

    一.Tomcat的简单介绍 大家应该知道平时所说的C/S和B/S系统架构:C/S架构是基于客户端C和服务端S的,B/S架构是基于浏览器B和S服务端的,B/S架构中的server就是web服务器. To ...

  10. 实验十二:SWING界面设计

    实验程序: import java.awt.FlowLayout;import javax.swing.*;import java.awt.Container;public class jianli ...