题目链接

https://atcoder.jp/contests/agc029/tasks/agc029_e

题解

写了一半发现假了然后强行乱改一通改对了……
我们用“\(u\)子树内小于\(x\)的连通块”来表示\(u\)子树内到\(u\)路径上的点都小于\(x\)的点(包括\(u\))的集合,集合的大小用\(C(u,x)\)表示。
考虑这个游走的过程,设点\(u\)到根的路径上分别是\(u=u_1,u_2,u_3,...,u_{k-1},u_k=1\), 则对于\(i\)来说干的事情是“把\(u_i\)子树内小于\(u_{i+1}\)的连通块都走一遍”。那么对于一个\(i\)来说若存在\(j>i\)且\(u_{j+1}>u_{i+1}\), 那么后者的作用会包含前者,前者无用。也就是说我们要考虑根到每个点路径上的前缀最大值(就是每个点到根路径上的后缀最大值)。
考虑递推,从父亲递推到儿子。设\(mx[u]\)表示\(u\)到根路径上的最大值,\(v\)是\(u\)的儿子,经过简单推导可得如下递推式:

ans[v] = ans[u];
if(u>mx[fa[u]]) {ans[v] += C(v,mx[u])-C(v,mx[fa[u]]);} //u是前缀最大值点
if(v>mx[u]) {ans[v] += 所有v的儿子v'的C(v',mx[u])之和+1;} //v是前缀最大值点

第三行是因为v>mx[u]所以v的子树不被包括在上一次的最大值点计算的贡献中,需要重新计算。
(我知道这样讲很不清楚……可是抱歉博主实在是不知道如何用文字把这个推导过程写清楚,并且这个实际上也挺简单的仔细推一推应该能推出来)
现在考虑如何对每个前缀最大值的\(u\)的每个儿子\(v\)求出\(C(v,mx[u])\)和\(C(v,mx[fa[u]])\). 看起来需要数据结构,但是我们发现所有这些值的总和是\(O(n)\)级别的,所以暴力枚举就可以了。
时间复杂度\(O(n)\).

代码

#include<bits/stdc++.h>
#define llong long long
#define mkpr make_pair
#define riterator reverse_iterator
using namespace std;inline int read()
{int x = 0,f = 1; char ch = getchar();for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}return x*f;
}const int N = 2e5;
struct Edge
{int nxt,v;
} e[(N<<1)+3];
int fe[N+3];
int fa[N+3];
int mx[N+3];
int f[N+3],g[N+3],h[N+3];
int ans[N+3];
int n,en;void addedge(int u,int v)
{en++; e[en].v = v;e[en].nxt = fe[u]; fe[u] = en;
}int dfs2(int u,int x)
{if(u>x) return 0;int ret = 1;for(int i=fe[u]; i; i=e[i].nxt){int v = e[i].v; if(v==fa[u]) continue;ret += dfs2(v,x);}return ret;
}void dfs1(int u)
{for(int i=fe[u]; i; i=e[i].nxt){int v = e[i].v; if(v==fa[u]) continue;fa[v] = u;mx[v] = max(mx[u],v);dfs1(v);}if(u>mx[fa[u]]){h[u] = 1;for(int i=fe[u]; i; i=e[i].nxt){int v = e[i].v; if(v==fa[u]) continue;f[v] = dfs2(v,u);g[v] = dfs2(v,mx[fa[u]]); h[u] += g[v];}}
}void dfs3(int u)
{for(int i=fe[u]; i; i=e[i].nxt){int v = e[i].v; if(v==fa[u]) continue;ans[v] = ans[u]; if(u>mx[fa[u]]) {ans[v] += f[v]-g[v];} if(mx[v]>mx[u]) {ans[v] += h[v];}dfs3(v);}
}int main()
{scanf("%d",&n);for(int i=1; i<n; i++){int u,v; scanf("%d%d",&u,&v);addedge(u,v); addedge(v,u);}mx[1] = 1; f[1] = 1; dfs1(1);
//  printf("f: "); for(int i=1; i<=n; i++) printf("%d ",f[i]); puts("");
//  printf("g: "); for(int i=1; i<=n; i++) printf("%d ",g[i]); puts("");
//  printf("h: "); for(int i=1; i<=n; i++) printf("%d ",h[i]); puts("");dfs3(1);for(int i=2; i<=n; i++) printf("%d ",ans[i]); puts("");return 0;
}

AtCoder AGC029E Wandering TKHS相关推荐

  1. AGC029 E: Wandering TKHS

     E: Wandering TKHS - AtCoder Grand Contest 029 | AtCoder 分类讨论好题(也不太算分类讨论) 方法:感受过程手玩,考虑能不能提前预算一些东西,或者 ...

  2. 【学习笔记】AGC009/AGC019/AGC029/AGC035

    AGC009 Eternal Average 奥妙重重 如果我们用树的结构来描述操作,设一个点的深度为xix_ixi​,那么一定满足∑k−xi=1\sum k^{-x_i}=1∑k−xi​=1,并且 ...

  3. AtCoder题解 —— AtCoder Beginner Contest 182 —— D - Wandering

    题目相关 题目链接 AtCoder Beginner Contest 182 D 题,https://atcoder.jp/contests/abc182/tasks/abc182_d. Proble ...

  4. 【做题记录】AtCoder AGC做题记录

    做一下AtCoder的AGC锻炼一下思维吧 目前已做题数: 127 总共题数: 269 每一场比赛后面的字母是做完的题,括号里是写完题解的题 AGC001: ABCDEF (DEF) AGC002: ...

  5. Atcoder题解与视频集

    开启Atcoder之路 开启Atcoder之路_sortmin的博客-CSDN博客_atcoder怎么用 atcoder心得 atcoder心得_404REN的博客-CSDN博客_atcoder怎么用 ...

  6. HDU 6229 Wandering Robots 找规律+离散化

    题目链接:Wandering Robots 题解:先讲一下规律,对于每一个格子它可以从多少个地方来有一个值(可以从自己到自己),然后答案就是统计合法格子上的数与所有格子的数的比值 比如说样例的3 0格 ...

  7. ICPC / CCPC / Codeforces / AtCoder 单词本

    过不了六级的小菜鸡呜呜呜,好久没有背过单词了,都忘完了 放一些写ICPC真题 / CCPC真题 / Codeforces / AtCoder 的时候不能立刻反应过来的单词每天背一下 四舍五入 roun ...

  8. 【每日亿题#12】AtCoder Grand Contest 021 (A ~ F)全部题解

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 文章目录 AtCoder Grand Contest 021 题解 A. Digit Sum 2 B. ...

  9. AtCoder Beginner Contest 202 D - aab aba baa(组合计数,字典序)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Problem 有 AAA 和 aaa,BBB 个 bbb ,可以使用这 A+BA+BA+B 个字符任 ...

最新文章

  1. 竞赛专题(四)特征工程-竞赛中的必杀技
  2. php dlt645,DLMS - DLT645规约转换模块
  3. android动态更改布局宽高,动态更改Android上的线性布局宽度或高度
  4. oracle 12 问题:需要 Oracle 客户端软件 8.1.7 或更高版本
  5. C# 扩展集合ObservableCollection使集合在添加、删除、值变更后触发事件
  6. Android Studio调试时遇见Install Repository and sync project的问题
  7. 图片格式转换大小调整工具_如何轻松快速地将图片转换到JPG/JPEG/PNG/BMP/TIFF
  8. [译]Windows 登录时间太长的案例
  9. 1.PHP与Web页面的交互
  10. 计算机应用可分为哪两类,计算机应用简答题
  11. 计算机四级c语言题库及答案,计算机四级考试题库及答案
  12. python自动化webdriver_轻松自动化---selenium-webdriver(python) (六)
  13. 摄像机标定:像素焦距与毫米焦距转换
  14. L3-020 至多删三个字符 (30 分)
  15. cmake交叉编译mbedtls,open62541笔记
  16. BUUCTF Web 极客大挑战 2019 EasySQL
  17. FPGA Vs 单片机 -- 嵌入式设计的另一种方法
  18. Vue\React\Angular的区别
  19. Django企业开发读书笔记(及官方文档学习笔记) 老男孩2019Go语言视频学习
  20. SURF网格化特征点提取算法流程(一)

热门文章

  1. sqlserver存储过程的参数传递注意事项
  2. 合并排序的非递归实现(自底向上设计)
  3. C++ 与 G++的区别
  4. MyBatis-Plus 高级功能 —— 实现逻辑删除
  5. springboot学习笔记(三)
  6. STM32F4 HAL库开发 -- 工程模板解读
  7. C语言再学习 -- 常用头文件和函数(转)
  8. 大数运算(8)——大数幂运算
  9. gRPC学习记录(二)--Hello World
  10. Android Framework常用工具及LOG调试方法