分析:好神的一道题啊.对每棵树建个图跑一下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. bzoj 1783: [Usaco2010 Jan]Taking Turns【贪心+dp】

    不知道该叫贪心还是dp 倒着来,记f[0][i],f[1][i]分别为先手和后手从n走到i的最大值.先手显然是取最大的,当后手取到比先手大的时候就交换 #include<iostream> ...

  2. springboot(一) 热部署

    代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo 1.热部署的定义 所谓的热部署:比如项目的热部署,就是在应用 ...

  3. No task executor bean found for async processing: no bean of type TaskExecut

    使用springcloud,添加异步方法后,调用异步成功,但有个 No task executor bean found for async processing: no bean of type T ...

  4. loadrunner中get和post请求

    loadrunner中可以使用web_url和web_link发送get请求,使web_submit_form和web_sumbit_data发送post请求. 有什么不同呢?推荐使用哪一个? web ...

  5. [Usaco2018 Open]Milking Order

    Description Farmer John的N头奶牛(1≤N≤10^5),仍然编号为1-N,正好闲得发慌.因此,她们发展了一个与Farmer John每天早上为她们挤牛奶的时候的排队顺序相关的复杂 ...

  6. Too many open files故障解决一例

    Linux环境WebSphere输出日志: [// ::: EDT] 000090b7 SystemErr R Caused by: java.io.FileNotFoundException: /o ...

  7. android序列化(2)Parcelable与Parcel

    1.简介 Parcel  : 包裹 Android采用这个它封装消息数据.这个是通过IBinder通信的消息的载体.需要明确的是Parcel用来存放数据的是内存(RAM),而不是永久性介质(Nand等 ...

  8. mysqli 进一步分析

    1. 一.mysql与mysqli的概念相关: 1.mysql与mysqli都是php方面的函数集,与mysql数据库关联不大. 2.在php5版本之前,一般是用php的mysql函数去驱动mysql ...

  9. Java编程思想读书笔记_第6章(访问权限)

    四种访问权限: public private 包访问权限 protected 如果没有明确指定package,则属于默认包 package access.dessert; public class C ...

  10. Python学习日记之忽略删除字符串空白

    使用Python自带的函数strip可以剔除字符串开头.结尾.两端的空白 使用场景:用户输入验证 strip : 去除字符串两端的空白 rstrip : 去除字符串末尾(右端)的空白 lstrip : ...