noip模拟赛 洗衣
分析:好神的一道题啊.对每棵树建个图跑一下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模拟赛 洗衣的更多相关文章
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...
- 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...
- 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
- CH Round #52 - Thinking Bear #1 (NOIP模拟赛)
A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...
随机推荐
- bzoj21012101: [Usaco2010 Dec]Treasure Chest 藏宝箱(滚动数组优化dp)
2101: [Usaco2010 Dec]Treasure Chest 藏宝箱 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 592 Solved: ...
- javascript实现继承的4种方法,以及它们的优缺点
1. 原型链继承(有缺陷): 缺陷1:切断了Zi.prototype.constructor与Zi的关系 缺陷2:原型链上的引用类型的数据会被所有实例共享 2. 构造函数继承(有缺陷): 缺陷1:Fu ...
- 洛谷 P1064 金明的预算方案(有依赖的背包问题)
题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”.今 ...
- windows 中常用的 cmd 命令汇总
查看系统基本信息: cmd -> systeminfo 或 run -> dxdiag 查询主板出厂日期: cmd -> wmic bios get releasedate 关闭本地 ...
- Redis基础---链接管理
Redis连接 Redis AUTH命令是用来向服务器验证给定的密码. 如果密码与在配置文件中的口令相匹配,则服务器会返回OK状态码,并开始接受命令.否则,将返回一个错误,并且客户需要尝试新的密码. ...
- 图标文件ico制作以及使用说明
今天说一个图标文件——ico.我们在pc端浏览网页的时候网页栏那块都会显示一个本网站特有的图片,就是我们说的ico了.示例:<link href="image/favicon.ico& ...
- 【转】jvm收集器
HotSpot JVM收集器 上面有7中收集器,分为两块,上面为新生代收集器,下面是老年代收集器.如果两个收集器之间存在连线,就说明它们可以搭配使用. Serial(串行GC)收集器 Serial收集 ...
- react Native环境 搭建
react Native的优点:跨平台 低投入高回报 性能高 支持动态更新.一才两用(ios和Android) 开发成本第 代码复用率高.windows环境搭建react Native开发环境1.安装 ...
- 定时器tasktimer
1.web.xml中配置 <servlet> <servlet-name>TaskTimer</servlet-name> <servlet-class> ...
- HDU_3182_Hamburger Magi_状态压缩dp
Hamburger Magi Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...