正题

题目链接:https://uoj.ac/problem/84


题目大意

有nnn个点的一棵树,111为根,两个人从根节点往下走(只能从深度小的点走到深度大的点)。

两个人每一秒都可以一条边(也可以不移动),或者不消耗时间将一个人传送到另一个人那里。

求遍历整棵树需要的最少时间。

1≤n≤5×1061\leq n\leq 5\times 10^61≤n≤5×106


解题思路

什么神仙题。

首先考虑到肯定存在一种方案使得一个人不需要使用传送,因为显然两个人都需要使用传送的方案可以通过交换两个人的某些路径得到有一个人不需要传送的方案。

那么说明其中一个人的路径肯定是一条链,我们将这个人称之为本体,另一个人称为分身。

然后一个粗暴的想法是dpdpdp出一条路径,然后本体每走到一个点就等分身遍历完除了链上的其他子树再往下一个节点走。设fif_ifi​表示走到节点iii的答案。

但是这样显然是会出问题的,对于节点xxx不一定是从它的父亲处转移的,因为两个人可以同时移动,当分身最后一次传送后本体可以和分身一起移动然后本体在下一个路口等分身传送。

让本体等分身是一种可能更赚的方案如图(边长代指了中间省略的点数量级别)

显然当本体等待分身遍历完1∼51\sim 51∼5之后让本体和分身分别走向444和333是更优的做法。

可以相当于在链上选择一些关键点,本体只有在关键点时才等待,并且分身最后遍历最深的叶子时本体同时出发。而关键点不连续的条件只有本体等分身的时才会出现,也就是分身最后遍历的叶子深度比下一个关键点的深度要大。

而且显然地如果出现了这种情况那么选择另一个深度更小的祖先作为上一个关键点不可能更优(因为会走同一段)

所以我们只需要对于每个节点xxx找到第一个祖先yyy满足yyy的子树除去xxx的子树后存在一个深度比xxx大的节点记为sfxsf_xsfx​。

那么每个节点只需从sfxsf_xsfx​转移即可,如果找不到sfsfsf的节点显然对于这样的节点它的父节点只会有一个子节点,那么令fx=ffax+1f_x=f_{fa_x}+1fx​=ffax​​+1即可。

问题是如何快速的求出每个sfxsf_xsfx​,注意到对于一个处理好的子树xxx只有可能有一段连续的链没有sfxsf_xsfx​(如图红色箭头所指部分)

所以我们只需要从小往上处理维护每个处理好的子树的sfsfsf为000的链。

然后两棵子树的时候我们直接暴力合并这些部分即可,因为合并完之后肯定只会留下长的那条链多出来的部分。

时间复杂度:O(n)O(n)O(n)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=5e6+10;
ll n,ans,deg[N],dep[N],fa[N],sf[N];
ll siz[N],sum[N],mx[N],nxt[N],f[N];
char s[N<<1];
void addl(ll x,ll y){deg[x]++;fa[y]=x;dep[y]=dep[x]+1;return;
}
signed main()
{scanf("%lld",&n);if(n==1)return puts("0")&0;scanf("%s",s+1);for(ll i=1,now=0,cnt=0;i<=2*n;i++){if(s[i]=='(')++cnt,addl(now,cnt),now=cnt;else now=fa[now];}for(ll i=n;i>1;i--){if(!deg[i])siz[i]=1,sum[i]=mx[i]=dep[i];ll x,y;for(x=i;x&&dep[x]<=mx[fa[i]];x=nxt[x])sf[x]=fa[i];for(y=nxt[fa[i]];y&&dep[y]<=mx[i];y=nxt[y])sf[y]=fa[i];nxt[fa[i]]=x+y;sum[fa[i]]+=sum[i];siz[fa[i]]+=siz[i];mx[fa[i]]=max(mx[fa[i]],mx[i]);}f[1]=0;ans=n*n+100;for(ll i=2;i<=n;i++){f[i]=n*n+100;ll x=sf[i];if(x)f[i]=f[x]+sum[x]-sum[i]-dep[x]*(siz[x]-siz[i]);if(deg[fa[i]]==1)f[i]=min(f[i],f[fa[i]]+1);if(!deg[i])ans=min(ans,f[i]);}printf("%lld\n",ans);return 0;
}

UOJ#84-[UR #7]水题走四方【dp】相关推荐

  1. 【UR #7】水题走四方

    题目描述 今天是世界水日,著名的水题资源专家蝈蝈大臣发起了水题走四方活动,向全世界发放成千上万的水题. 蝈蝈大臣是家里蹲大学的教授,当然不愿意出门发水题啦!所以他委托他的助手欧姆来发. 助手欧姆最近做 ...

  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. 水题 ZOJ 3875 Lunch Time

    题目传送门 1 /* 2 水题:找排序找中间的价格,若有两个,选价格大的: 3 写的是有点搓:) 4 */ 5 #include <cstdio> 6 #include <iostr ...

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

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

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

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

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

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

最新文章

  1. 2021年大数据Hadoop(十):HDFS的数据读写流程
  2. mysql 主从复制优化、并行复制
  3. SQL LEFT JOIN与IN使用案例说明
  4. Python之IPython开发实践
  5. 如何实现软件的远程更新_手机免root终于也能实现远程控制了 这款国产软件真是越来越好用...
  6. plantuml 方法图_UML与软件建模:第四次作业(学习PlantUML活动图绘制方法)
  7. c# union结构体_P/Invoke各种总结(八、在C#中使用Union联合体)
  8. Bailian2681 求字符串长度【字符串】
  9. 国家测绘局制定的测绘与地理信息行业标准统计 (20110706)
  10. GPRS通信原理+中国移动micro sim 卡,实现经过tcp/ip 传输数据到服务器
  11. sola病毒的手工杀除
  12. Google 镜像站
  13. 计算机网络信息安全等级保护(等保)
  14. 用ln命令链接文件 --- 一根绳子上的蚂蚱?
  15. 有了AI智能绘画,我也可以成为绘画大师——全球最大规模中文跨模态生成模型ERNIE-ViLG
  16. 倍福plc的型号_EL9186——plc倍福模块+EL9100型号EL9010
  17. 如何实现rsync远程同步和inotify实时同步
  18. 【功能实现】qrcode生成二维码Demo
  19. EA001-186-2220-蓝豪杰
  20. Android Received status code 502 from server: Bad Gateway

热门文章

  1. 移动计算机怎么开机密码,win7忘记开机密码解决办法
  2. mysql 5.7.6 5.7.19_MySQL数据库之Mysql 5.7.19 免安装版遇到的坑(收藏)
  3. oracle 如何筛选重复,求sql--筛选A字段相同,B字段不同且不重复的记录
  4. 苹果手机运行python_iPhone是卖的最好的手机?用Python照样把他玩弄鼓掌之间!
  5. mysql group by 范围_MySQL 按照范围/等级 进行Group By
  6. 「软件项目管理」一文了解软件项目团队计划
  7. DEBUG org.springframework.web.servlet.DispatcherServlet - Error rendering view [org.thymeleaf.spring
  8. 图的建立-邻接矩阵表示(C语言)
  9. poj2182 Lost Cows-线段树
  10. 高等数学上-赵立军-北京大学出版社-题解-练习2.7