题目描述

今天是世界水日,著名的水题资源专家蝈蝈大臣发起了水题走四方活动,向全世界发放成千上万的水题。

蝈蝈大臣是家里蹲大学的教授,当然不愿意出门发水题啦!所以他委托他的助手欧姆来发。

助手欧姆最近做 UR #6 被狗狗传染了懒癌,当然不愿意出门发水题啦!所以他请来了高手 —— 地卜师。

全世界一共 n 个城市,编号分别为 1,…,n。城市之间由双向道路相连,形成了一棵树。如果这棵树以 1 为根,则除 1 以外每个结点 v 的父亲结点的编号 pv 满足 pv<v。

由于地卜师掌握了克隆的核心科技,把自己完全复制了一份,他和他的分身一共两个地卜师一起出去执行任务。

现在,两个地卜师都站在 1 号城市。地卜师可以沿道路行走,从一个城市移动到另一个城市。走一条道路需要耗时 1 小时。当然,地卜师可以停留在某个城市不动。每到一个没有发放水题的城市,地卜师都会发水题。在一个城市里发水题的时间不计。

由于地卜师有强迫症,他沿道路移动时总是从一个城市移动到编号更大的城市。即总是从一个结点移动到它的儿子结点。地卜师和他的分身可以同时移动

但是地卜师这样好像不一定能经过所有的城市?没关系!地卜师会瞬移。如果某个时刻两个地卜师都在某个城市里(而不是在去某个城市的道路上),那么其中一个地卜师可以瞬移到另一个地卜师所在的城市。瞬移所需的时间不计。

现在地卜师想知道,要想顺利给每个城市都发放水题,最短需要多少个小时。

欧姆当然知道怎么计算啦!但是他想考考你。

题解 

神仙题.png。

我们可以先考虑最优解是怎么走出来的。

先是这个人和它的分身,初步的想法是他们俩来到了一个节点,然后分身去遍历这颗子树的一些儿子中的叶子结点。

最后剩一个儿子,然后它俩一块走到下一个儿子里面。

但是这种想法少考虑了一些情况(反例就不说了,也就是说不能只考虑往儿子走)。

我们可以将两个人同时停留的地方称作关键点,显然所有的关键点都在一条链上。

那么分身应该遍历这颗子树减去下一颗关键点所在子树的那颗子树的所有叶子结点。

就是在分身遍历最后一个叶子的时候,这个人可以同时往下一个关键点走,等到两个人都到了自己该到的地方,分身再TP到这个人那里。

然后有一个初步的dp想法,就是设dp[i]表示i是一个关键点,两个人第一次到这个点所用的最小时间。

转移:

nl:当前子树内的叶子节点个数,ds:当前子树内叶子结点的深度和,dm[u][v]:u的子树扣掉v的子树后最深的叶子结点的深度,d:节点深度。

更正:上面的第二个min为max。

后面那个东西是在讨论这个人和分身谁先到目的地。

这个dp是n^2的,好像有各种高科技的优化办法然而并不会。。。

我们发现这个式子前面那一坨好像可优化性不大。

考虑后面那个max可不可以为0,那么相当于是说找到一个祖先u使得d[v]<=dm[u,v]。

如果我们对于每个点都找出这个祖先的话,转移就轻松完成了。

我们考虑是不是所有点都能找到这个祖先,肯定不是的,当一个点的deep满足没有其他点和它deep相等时这个点是没有这种祖先的。

这样的点有什么神奇的规律?它们是连续的一条链,就是这个样子的。

一棵树下面多出来的这条链。

因为我们是在叶子的位置统计答案,那么有结论,最优解肯定不在这种叶子上(想想为什么)。

那么我们的任务就变成找这种神奇祖先了。

首先这种神奇祖先肯定是越低越好。

我们可以维护一个链表表示还没找到祖先的节点,在子树合并的时候互相更新一下(因为两颗子树的maxdeep都可以作为更新答案的条件)。

这是最多只会有一颗子树内有节点没有找到祖先(想想为什么),所以我们维护的复杂度是线性的。

代码

#include<iostream>
#include<cstdio>
#define N 5000009
#define inf 1e18
using namespace std;
typedef long long ll;
inline ll rd(){ll x=0;char c=getchar();bool f=0;while(!isdigit(c)){if(c=='-')f=1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}return f?-x:x;
}
ll n,deep[N],mx_deep[N],sum_deep[N],cnt[N],dp[N];
int nxt[N],up[N],son[N],tot,fa[N];
char s[N<<1];
int main(){n=rd();scanf("%s", s);int v;for(int i=0;i<n*2;i++){if(s[i]=='('){tot++;fa[tot]=v; v=tot;}else v=fa[v];}for(int i=2;i<=n;++i){if(fa[i])son[fa[i]]++;deep[i]=deep[fa[i]]+1;}for(int i=n;i>=2;--i){if(!son[i]){mx_deep[i]=sum_deep[i]=deep[i];cnt[i]=1;}int now=i;while(now&&deep[now]<=mx_deep[fa[i]]){up[now]=fa[i];now=nxt[now];}while(nxt[fa[i]]&&deep[nxt[fa[i]]]<=mx_deep[i]){up[nxt[fa[i]]]=fa[i];nxt[fa[i]]=nxt[nxt[fa[i]]];}if(now)nxt[fa[i]]=now;mx_deep[fa[i]]=max(mx_deep[fa[i]],mx_deep[i]);sum_deep[fa[i]]+=sum_deep[i];cnt[fa[i]]+=cnt[i];}ll ans=inf;for(int i=2;i<=n;++i){dp[i]=inf;if(up[i])dp[i]=dp[up[i]]+sum_deep[up[i]]-sum_deep[i]-(cnt[up[i]]-cnt[i])*deep[up[i]];if(son[fa[i]]==1)dp[i]=min(dp[fa[i]]+1,dp[i]);if(!son[i])ans=min(ans,dp[i]);}if(n==1){puts("0");return 0;}cout<<ans;return 0;
}

转载于:https://www.cnblogs.com/ZH-comld/p/10360417.html

【UR #7】水题走四方相关推荐

  1. UOJ#84-[UR #7]水题走四方【dp】

    正题 题目链接:https://uoj.ac/problem/84 题目大意 有nnn个点的一棵树,111为根,两个人从根节点往下走(只能从深度小的点走到深度大的点). 两个人每一秒都可以一条边(也可 ...

  2. 第四战:“合纵”与“连横”(“战国纵横家书”辨别修订版)诸子百家走四方的美好时代

    link 话说商鞅被车裂后,秦惠王恨他归恨他,但却很理智,商鞅的一系列方针政策继续沿用. 因为他发现商鞅打造的这台国家机器太好用了,短短二十年的时间,秦国从被看不起的西戎小国到被周天子官方封为西部大总 ...

  3. 图论刷水题记录(二)(最短路-----SPFA算法)

    继第一篇的后续,又来刷水题了,写的是SPFA算法,这个算法的复杂度比较玄学,感觉能不用就不用了,但是他的好处就是可以判断负圈. 3月26日: 1.POJ 1847 Tram 题意:在一个交通网络上有N ...

  4. hdu 2041:超级楼梯(水题,递归)

    超级楼梯Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submissio ...

  5. hdu4530 水题

    题意: 小Q系列故事--大笨钟 Time Limit: 600/200 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total ...

  6. 闲来无事刷水题、简单博弈论专题、sg函数、洛谷

    记 今天闲来无事,不想刷codeforces了,到洛谷提高组训练营找几道水题刷着玩玩(虽然自己早已过了打OI的年纪)- 简单博弈论专题 P1199 三国游戏 这么考虑,由于电脑总是不能让我搭配出当前能 ...

  7. HDU2186 一定要记住我爱你【水题】

    悼念512汶川大地震遇难同胞--一定要记住我爱你 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...

  8. CodeForces Canada Cup 2016 A、B水题 _(:з」∠)_

    哭哭哭哭哭哭哭 又降了4...... 这次吸取的教训是...本来就是个做题慢的傻逼....一定要准时题目一开就开始做.....不然就等着降名次吧,..... 开始四十多分钟才开进去的.....再给我四 ...

  9. 寒假每日一题题解(1.29)摘花生(DP水题)

    摘花生 Hello Kitty想摘点花生送给她喜欢的米老鼠. 她来到一片有网格状道路的矩形花生地(如下图),从西北角进去,东南角出来. 地里每个道路的交叉点上都有种着一株花生苗,上面有若干颗花生,经过 ...

最新文章

  1. 计算机书籍:新媒体运营
  2. html载入字体,css怎么导入字体?
  3. ALV输出无法指定STATUS
  4. (五)Vue 面试真题演练
  5. sqrt()函数的注意事项
  6. 学好Java开发的关键七步
  7. C语言 文件缓冲区
  8. des算法c语言运行成功截图,求助攻:C语言DES算法的实现程序有问题
  9. TensorFlow2.0:误差计算
  10. 如何搞定高并发系统设计?
  11. linux内核zfs,ZFS与Linux文件系统的变革
  12. JDBC08时间处理
  13. 恶意代码分析实战 lab1-4
  14. Application Virtualization 4.5 部署【3】
  15. 如果你现在没有目标,对未来很迷茫、、打扰下 耽误几秒钟看看这个故事 故事很短 但是你一定会有所收获。...
  16. 超级强大的淘宝开源平台(taobao-code)
  17. Java游戏编程不完全详解-1
  18. http实现大文件上传
  19. 新中新 金龙一卡通 TPE_StartTPE 加载授权文件失败 JAVA
  20. 书法练习轨迹ReadMe

热门文章

  1. Android根据图片名字获取图片ID
  2. Python request简单使用
  3. 神经网络实现逻辑运算,神经网络 最小二乘法
  4. 带头双向循环链表的模拟实现
  5. 7:1 error Expected indentation of 2 spaces but found 4 indent 11:35 error Newline requir
  6. tikz包 安装_TikZ: LaTeX绘图包
  7. idea几款好用的插件
  8. 2022,世界杯,来了
  9. MBA-day33 绝对值的几何意义
  10. java与JSON语法及解析