\(\mathcal{Description}\)

  \(n\) 个点,第 \(i\) 个点能走向第 \(d_i\) 个点,但从一个点出发至多走 \(k\) 步。对于每个点,求有多少点能够走到它。

  \(n\le5\times10^5\)。

\(\mathcal{Solution}\)

  显然这些点构成一片内向基环树森林。考虑每个点的贡献,若其向上走 \(k\) 步仍不能到环上,那一定只在树内对一条链贡献,树上差分一下。否则,该点会向到根的每个点贡献,并向环上一段连续的点贡献,后者维护一个数列差分亦可统计,就切掉啦。

  复杂度 \(\mathcal O(n)\)。

\(\mathcal{Code}\)

  1. #include <cstdio>
  2. #include <vector>
  3. #include <algorithm>
  4. inline int rint () {
  5. int x = 0; char s = getchar ();
  6. for ( ; s < '0' || '9' < s; s = getchar () );
  7. for ( ; '0' <= s && s <= '9'; s = getchar () ) x = x * 10 + ( s ^ '0' );
  8. return x;
  9. }
  10. inline void wint ( const int x ) {
  11. if ( 9 < x ) wint ( x / 10 );
  12. putchar ( x % 10 ^ '0' );
  13. }
  14. const int MAXN = 5e5;
  15. int n, K, d[MAXN + 5], ans[MAXN + 5], stk[MAXN + 5], top, ccnt;
  16. bool vis[MAXN + 5], oncir[MAXN + 5], inq[MAXN + 5];
  17. int dep[MAXN + 5], fa[MAXN + 5], dir[MAXN + 5], tag[MAXN + 5], add[MAXN * 2 + 5];
  18. std::vector<int> cir[MAXN + 5], adj[MAXN + 5];
  19. inline void findCir ( const int u ) {
  20. if ( vis[u] ) return ;
  21. vis[u] = true, stk[++ top] = u, inq[u] = true;
  22. if ( inq[d[u]] ) {
  23. int v; ++ ccnt;
  24. do {
  25. oncir[v = stk[top --]] = true;
  26. cir[ccnt].push_back ( v );
  27. } while ( v ^ d[u] );
  28. std::reverse ( cir[ccnt].begin (), cir[ccnt].end () );
  29. }
  30. findCir ( d[u] ), inq[u] = false;
  31. }
  32. inline void solveTree ( const int u, int p, const int rtid, const int L ) {
  33. ++ tag[u];
  34. if ( dep[u] <= K ) {
  35. int tar = K - dep[u] + 1;
  36. if ( tar >= L ) tar = L - 1;
  37. ++ add[rtid + 1], -- add[rtid + 1 + tar];
  38. } else {
  39. -- tag[fa[p]], p = dir[p];
  40. }
  41. for ( int i = 0, v; i ^ adj[u].size (); ++ i ) {
  42. if ( !oncir[v = adj[u][i]] ) {
  43. dep[dir[u] = v] = dep[u] + 1, fa[v] = u;
  44. solveTree ( v, p, rtid, L );
  45. }
  46. }
  47. }
  48. inline int calc ( const int u ) {
  49. int ret = tag[u];
  50. for ( int i = 0, v; i ^ adj[u].size (); ++ i ) {
  51. if ( !oncir[v = adj[u][i]] ) {
  52. ret += calc ( v );
  53. }
  54. }
  55. return ans[u] += ret, ret;
  56. }
  57. inline void solveCir ( std::vector<int>& cir ) {
  58. int L = cir.size ();
  59. for ( int i = 0; i <= L << 1; ++ i ) add[i] = 0;
  60. for ( int i = 0, u; i < L; ++ i ) {
  61. dep[u = cir[i]] = 1;
  62. solveTree ( u, u, i, L ), calc ( u );
  63. }
  64. for ( int i = 1; i < L * 2; ++ i ) add[i] += add[i - 1];
  65. for ( int i = 0; i < L; ++ i ) ans[cir[i]] += add[i] + add[i + L];
  66. }
  67. int main () {
  68. freopen ( "travel.in", "r", stdin );
  69. freopen ( "travel.out", "w", stdout );
  70. n = rint (), K = rint ();
  71. for ( int i = 1; i <= n; ++ i ) adj[d[i] = rint ()].push_back ( i );
  72. for ( int i = 1; i <= n; ++ i ) top = 0, findCir ( i );
  73. for ( int i = 1; i <= ccnt; ++ i ) solveCir ( cir[i] );
  74. for ( int i = 1; i <= n; ++ i ) wint ( ans[i] ), putchar ( '\n' );
  75. return 0;
  76. }

\(\mathcal{Details}\)

  考场上想得久了点 qwq……最神奇的是兔子爆排一般是因为标算写假而测试代码是对的。(

Solution -「LOCAL」人口迁徙的更多相关文章

  1. Solution -「LOCAL」二进制的世界

    \(\mathcal{Description}\)   OurOJ.   给定序列 \(\{a_n\}\) 和一个二元运算 \(\operatorname{op}\in\{\operatorname{ ...

  2. Solution -「LOCAL」大括号树

    \(\mathcal{Description}\)   OurTeam & OurOJ.   给定一棵 \(n\) 个顶点的树,每个顶点标有字符 ( 或 ).将从 \(u\) 到 \(v\) ...

  3. Solution -「LOCAL」过河

    \(\mathcal{Description}\)   一段坐标轴 \([0,L]\),从 \(0\) 出发,每次可以 \(+a\) 或 \(-b\),但不能越出 \([0,L]\).求可达的整点数. ...

  4. Solution -「LOCAL」Drainage System

    \(\mathcal{Description}\)   合并果子,初始果子的权值在 \(1\sim n\) 之间,权值为 \(i\) 的有 \(a_i\) 个.每次可以挑 \(x\in[L,R]\) ...

  5. Solution -「LOCAL」Burning Flowers

      灼之花好评,条条生日快乐(假装现在 8.15)! \(\mathcal{Description}\)   给定一棵以 \(1\) 为根的树,第 \(i\) 个结点有颜色 \(c_i\) 和光亮值 ...

  6. Solution -「LOCAL」画画图

    \(\mathcal{Description}\)   OurTeam.   给定一棵 \(n\) 个点的树形随机的带边权树,求所有含奇数条边的路径中位数之和.树形生成方式为随机取不连通两点连边直到全 ...

  7. Solution -「LOCAL」ZB 平衡树

    \(\mathcal{Description}\)   OurOJ.   维护一列二元组 \((a,b)\),给定初始 \(n\) 个元素,接下来 \(m\) 次操作: 在某个位置插入一个二元组: 翻 ...

  8. Solution -「LOCAL」舟游

    \(\mathcal{Description}\)   \(n\) 中卡牌,每种三张.对于一次 \(m\) 连抽,前 \(m-1\) 次抽到第 \(i\) 种的概率是 \(p_i\),第 \(m\) ...

  9. Solution -「LOCAL」充电

    \(\mathcal{Description}\)   给定 \(n,m,p\),求序列 \(\{a_n\}\) 的数量,满足 \((\forall i\in[1,n])(a_i\in[1,m])\l ...

随机推荐

  1. JSch Algorithm negotiation fail

    https://stackoverflow.com/questions/30846076/jsch-algorithm-negotiation-fail As you can see, the ser ...

  2. Go语言实战爬虫项目

    Go语言爬虫框架之Colly和Goquery Python爬虫框架比较多有requests.urllib, pyquery,scrapy等,解析库有BeautifulSoup.pyquery.Scra ...

  3. fluem读取文件并写入到hadoop的hdfs

    接上一章,本章介绍使用 crontab 像指定文件定时写入,使用fluem 读取并写入到hadoop的hdfs 前提准备已安装好fluem ,和hadoop(推荐单机即可毕竟做实验) 一.进入终端执行 ...

  4. DEEP LEARNING WITH PYTORCH: A 60 MINUTE BLITZ | TENSORS

    Tensor是一种特殊的数据结构,非常类似于数组和矩阵.在PyTorch中,我们使用tensor编码模型的输入和输出,以及模型的参数. Tensor类似于Numpy的数组,除了tensor可以在GPU ...

  5. netty系列之:请netty再爱UDT一次

    目录 简介 netty对UDT的支持 搭建一个支持UDT的netty服务 异常来袭 TypeUDT和KindUDT 构建ChannelFactory SelectorProviderUDT 使用UDT ...

  6. GeoServer课程规划

    "凡事豫则立,不豫则废." --西汉·戴圣<礼记·中庸> 为了做好GeoServer课程培训,需要拟定一个课程目录,对整个课程做一个宏观上的规划.有了这个规划,就有了目 ...

  7. HTTP-常用请求头

    HTTP-常用请求头 Accept:表示客户端可以接收的数据类型 Accpet-Language:表示客户端可以接收的语言类型 User-Agent:表示客户端浏览器的信息 Host:表示请求时的服务 ...

  8. 集合框架-ListIterator接口

    1 package cn.itcast.p4.list.demo; 2 3 import java.util.ArrayList; 4 import java.util.Iterator; 5 imp ...

  9. 开源免费的WordPress个人博客主题推荐

    二次元动漫类个人主题 Sakura 功能强大,美观大气,二次元动漫专属 演示地址:https://2heng.xin/theme-sakura/ 开源地址:https://github.com/mas ...

  10. openstack,docker,mesos,Kubernetes(k8s)

    作者:张乾链接:https://www.zhihu.com/question/62985699/answer/204233732来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...