题目:http://codeforces.com/problemset/problem/1059/E

用倍增可以在nlog内求出每个节点占用一个sequence 时最远可以向父节点延伸到的节点,对每个节点作为sequence 的最后一个元素向上延伸时,将节点的父节点属性合并(类似于并查集的操作),

存在优先队列里保证每次先操作dep最大的节点

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<queue>
  5. #include<vector>
  6. #include<string.h>
  7. #include<cstring>
  8. #include<algorithm>
  9. #include<set>
  10. #include<map>
  11. #include<fstream>
  12. #include<cstdlib>
  13. #include<ctime>
  14. #include<list>
  15. #include<climits>
  16. #include<bitset>
  17. #include<random>
  18. #include <ctime>
  19. #include <cassert>
  20. #include <complex>
  21. #include <cstring>
  22. #include <chrono>
  23. using namespace std;
  24. #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  25. #define fopen freopen("input.in", "r", stdin);freopen("output.in", "w", stdout);
  26. #define left asfdasdasdfasdfsdfasfsdfasfdas1
  27. #define set asfdasdasdfasdfsdfasfsdfasfdas2
  28. #define tan asfdasdasdfasdfasfdfasfsdfasfdas
  29. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  30. typedef long long ll;
  31. typedef unsigned int un;
  32. const int desll[][]={{,},{,-},{,},{-,}};
  33. const int mod=1e9+;
  34. const int maxn=1e5+;
  35. const int maxm=1e5;
  36. const double eps=1e-;
  37. const int csize=;
  38. int n,k,m,ar[maxn];
  39. int f[maxn],tan[maxn][],v[maxn],in[maxn],mark;
  40. ll ss[maxn][];
  41. bool ma[maxn],que[maxn];
  42. priority_queue<pair<int,int> > qu;
  43. vector<int> ve[maxn];
  44. int dep[maxn];
  45. void dfs(int u,int pre)
  46. {
  47. if(pre>=)dep[u]=dep[pre]+;
  48. for(int i=;i<ve[u].size();i++){
  49. int v=ve[u][i];
  50. if(v==pre)continue;
  51. dfs(v,u);
  52. }
  53. }
  54. int main()
  55. {
  56. int l;
  57. ll s,mx=;f[]=;
  58. scanf("%d%d%I64d",&n,&l,&s);
  59. memset(in,,sizeof(in));
  60. memset(tan,,sizeof(tan));
  61. memset(ma,,sizeof(ma));
  62. memset(que,,sizeof(que));
  63. for(int i=;i<=n;i++)scanf("%d",&ar[i]),mx=max(mx,1LL*ar[i]);
  64. for(int i=;i<=n;i++)scanf("%d",&f[i]),in[f[i]]++,ve[f[i]].push_back(i);
  65. dep[]=;
  66. dfs(,-);
  67. if(mx>s){
  68. printf("-1\n");
  69. return ;
  70. }
  71. for(int i=;i<=n;i++){
  72. tan[i][]=f[i];
  73. ss[i][]=ar[f[i]];
  74. }
  75. for(int j=;j<;j++){//倍增预处理
  76. for(int i=;i<=n;i++){
  77. if(i + (<<j) >n)break;
  78. tan[i][j]=tan[tan[i][j-]][j-];
  79. ss[i][j] = ss[i][j-]+ss[tan[i][j-]][j-];
  80. }
  81. }
  82. for(int i=;i<=n;i++){
  83. ll lmid=l-,smid=s-ar[i];
  84. int ins=,x=i;
  85. while(ins>=){
  86. if(tan[x][ins]==)ins--;
  87. else if((<<ins) > lmid)ins--;
  88. else if(ss[x][ins]<=smid){
  89. smid-=ss[x][ins];
  90. lmid -= (<<ins);
  91. x=tan[x][ins];
  92. }
  93. else ins--;
  94. }
  95. v[i]=x;//v[i]代表i节点作为sequence尾节点时最远可以向上延伸到的节点
  96. }
  97. for(int i=;i<=n;i++){
  98. if(v[i]==)exit();
  99. }
  100. for(int i=;i<=n;i++){
  101. if(in[i]==){
  102. qu.push(make_pair(dep[i],i));
  103. que[i]=;
  104. }
  105. }
  106. int ans=;
  107. while(qu.size()){
  108. int u=qu.top().second;qu.pop();
  109. if(ma[u])continue;//如果已经标记过,代表有其他节点可以延伸到此节点,跳过即可
  110. mark=v[u];
  111. int mid=f[u],pre=u;
  112. while(dep[mid]>dep[mark]){//对ma数组进行标记,合并f数组,类似于并查集的操作
  113. ma[pre]=;
  114. f[pre]=mark;
  115. pre=mid;
  116. mid=f[mid];
  117. }
  118. ma[pre]=;
  119. ma[mark]=;
  120. if(pre!=mark)f[pre]=mark;
  121. ans++;
  122. //cout<<mark<<" "<<f[mark]<<" "<<ma[f[mark]]<<" "<<que[f[mark]]<<endl;
  123. if(f[mark]> && !ma[f[mark]] && !que[f[mark]]){
  124. qu.push(make_pair(dep[f[mark]],f[mark]));
  125. que[f[mark]]=;
  126. }
  127. }
  128. printf("%d\n",ans);
  129.  
  130. return ;
  131. }

Codeforces 1059E. Split the Tree的更多相关文章

  1. Codeforces 461B. Appleman and Tree[树形DP 方案数]

    B. Appleman and Tree time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

  2. Codeforces 461B Appleman and Tree(木dp)

    题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k ...

  3. [Split The Tree][dfs序+树状数组求区间数的种数]

    Split The Tree 时间限制: 1 Sec  内存限制: 128 MB提交: 46  解决: 11[提交] [状态] [讨论版] [命题人:admin] 题目描述 You are given ...

  4. Codeforces 1129 E.Legendary Tree

    Codeforces 1129 E.Legendary Tree 解题思路: 这题好厉害,我来复读一下官方题解,顺便补充几句. 首先,可以通过询问 \(n-1​\) 次 \((S=\{1\},T=\{ ...

  5. Codeforces 280C Game on tree【概率DP】

    Codeforces 280C Game on tree LINK 题目大意:给你一棵树,1号节点是根,每次等概率选择没有被染黑的一个节点染黑其所有子树中的节点,问染黑所有节点的期望次数 #inclu ...

  6. Split The Tree

    Split The Tree 时间限制: 1 Sec  内存限制: 128 MB 题目描述 You are given a tree with n vertices, numbered from 1 ...

  7. [CodeForces1059E] Split the Tree

    树形DP. 用倍增处理出来每个点往上能延伸出去的最远路径,nlogn 对于每个节点,如果它能被后代使用过的点覆盖,就直接覆盖,这个点就不使用,否则就ans++,让传的Max改成dp[x] #inclu ...

  8. Codeforces A. Game on Tree(期望dfs)

    题目描述: Game on Tree time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  9. HDU6504 Problem E. Split The Tree【dsu on tree】

    Problem E. Split The Tree Problem Description You are given a tree with n vertices, numbered from 1 ...

随机推荐

  1. [Leetcode] Remove duplicates from sorted array 从已排序的数组中删除重复元素

    Given a sorted array, remove the duplicates in place such that each element appear only once and ret ...

  2. Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) C (用map 超时)

    C. Bear and Colors time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  3. JAVA中string.replace()和string.replaceAll()的区别及用法

    乍一看,字面上理解好像replace只替换第一个出现的字符(受javascript的影响),replaceall替换所有的字符,其实大不然,只是替换的用途不一样.    public String r ...

  4. php魔术方法的使用

    本文测试环境为 php5.5.12 一.__get .__set 将对象的属性进行接管. 一般来说,总是把类的属性定义为private,但是对属性的读取和赋值操作非常频繁,在php5+,预定义__se ...

  5. [POI2014] KUR-Couriers(洛谷P3567)

    洛谷题目链接:[POI2014]KUR-Couriers 题目描述 Byteasar works for the BAJ company, which sells computer games. Th ...

  6. Ubuntu下kafka集群环境搭建及测试

    kafka介绍: Kafka[1是一种高吞吐量[2]  的分布式发布订阅消息系统,有如下特性: 通过O(1)的磁盘数据结构提供消息的持久化,这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能 ...

  7. IntelliJ IDEA2017 + Tomcat 设置热部署

    1.点击idea中tomcat设置 2.点击deployment查看Deploy at the server startup 中tomcat每次所运行的包是 xxxx:war 还是其他,如果是xxxx ...

  8. [bzoj3884]上帝与集合的正确用法——欧拉函数

    题目大意 题解 出题人博客 代码 #include <bits/stdc++.h> using namespace std; const int M = 10001000; int phi ...

  9. Django【进阶】中间件

    中间件   一.概念 django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法. 其 ...

  10. python3 面向对象、类、继承、组合、派生、接口、子类重用父类方法

    对象是特征(变量)与技能(函数)的结合体而类是一系列对象共同的特征与技能的集合体 class teacher: lesson = "python" def __init__(sel ...