Codeforces 1059E. Split the Tree
题目:http://codeforces.com/problemset/problem/1059/E
用倍增可以在nlog内求出每个节点占用一个sequence 时最远可以向父节点延伸到的节点,对每个节点作为sequence 的最后一个元素向上延伸时,将节点的父节点属性合并(类似于并查集的操作),
存在优先队列里保证每次先操作dep最大的节点
- #include<iostream>
- #include<cstdio>
- #include<cmath>
- #include<queue>
- #include<vector>
- #include<string.h>
- #include<cstring>
- #include<algorithm>
- #include<set>
- #include<map>
- #include<fstream>
- #include<cstdlib>
- #include<ctime>
- #include<list>
- #include<climits>
- #include<bitset>
- #include<random>
- #include <ctime>
- #include <cassert>
- #include <complex>
- #include <cstring>
- #include <chrono>
- using namespace std;
- #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
- #define fopen freopen("input.in", "r", stdin);freopen("output.in", "w", stdout);
- #define left asfdasdasdfasdfsdfasfsdfasfdas1
- #define set asfdasdasdfasdfsdfasfsdfasfdas2
- #define tan asfdasdasdfasdfasfdfasfsdfasfdas
- mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
- typedef long long ll;
- typedef unsigned int un;
- const int desll[][]={{,},{,-},{,},{-,}};
- const int mod=1e9+;
- const int maxn=1e5+;
- const int maxm=1e5;
- const double eps=1e-;
- const int csize=;
- int n,k,m,ar[maxn];
- int f[maxn],tan[maxn][],v[maxn],in[maxn],mark;
- ll ss[maxn][];
- bool ma[maxn],que[maxn];
- priority_queue<pair<int,int> > qu;
- vector<int> ve[maxn];
- int dep[maxn];
- void dfs(int u,int pre)
- {
- if(pre>=)dep[u]=dep[pre]+;
- for(int i=;i<ve[u].size();i++){
- int v=ve[u][i];
- if(v==pre)continue;
- dfs(v,u);
- }
- }
- int main()
- {
- int l;
- ll s,mx=;f[]=;
- scanf("%d%d%I64d",&n,&l,&s);
- memset(in,,sizeof(in));
- memset(tan,,sizeof(tan));
- memset(ma,,sizeof(ma));
- memset(que,,sizeof(que));
- for(int i=;i<=n;i++)scanf("%d",&ar[i]),mx=max(mx,1LL*ar[i]);
- for(int i=;i<=n;i++)scanf("%d",&f[i]),in[f[i]]++,ve[f[i]].push_back(i);
- dep[]=;
- dfs(,-);
- if(mx>s){
- printf("-1\n");
- return ;
- }
- for(int i=;i<=n;i++){
- tan[i][]=f[i];
- ss[i][]=ar[f[i]];
- }
- for(int j=;j<;j++){//倍增预处理
- for(int i=;i<=n;i++){
- if(i + (<<j) >n)break;
- tan[i][j]=tan[tan[i][j-]][j-];
- ss[i][j] = ss[i][j-]+ss[tan[i][j-]][j-];
- }
- }
- for(int i=;i<=n;i++){
- ll lmid=l-,smid=s-ar[i];
- int ins=,x=i;
- while(ins>=){
- if(tan[x][ins]==)ins--;
- else if((<<ins) > lmid)ins--;
- else if(ss[x][ins]<=smid){
- smid-=ss[x][ins];
- lmid -= (<<ins);
- x=tan[x][ins];
- }
- else ins--;
- }
- v[i]=x;//v[i]代表i节点作为sequence尾节点时最远可以向上延伸到的节点
- }
- for(int i=;i<=n;i++){
- if(v[i]==)exit();
- }
- for(int i=;i<=n;i++){
- if(in[i]==){
- qu.push(make_pair(dep[i],i));
- que[i]=;
- }
- }
- int ans=;
- while(qu.size()){
- int u=qu.top().second;qu.pop();
- if(ma[u])continue;//如果已经标记过,代表有其他节点可以延伸到此节点,跳过即可
- mark=v[u];
- int mid=f[u],pre=u;
- while(dep[mid]>dep[mark]){//对ma数组进行标记,合并f数组,类似于并查集的操作
- ma[pre]=;
- f[pre]=mark;
- pre=mid;
- mid=f[mid];
- }
- ma[pre]=;
- ma[mark]=;
- if(pre!=mark)f[pre]=mark;
- ans++;
- //cout<<mark<<" "<<f[mark]<<" "<<ma[f[mark]]<<" "<<que[f[mark]]<<endl;
- if(f[mark]> && !ma[f[mark]] && !que[f[mark]]){
- qu.push(make_pair(dep[f[mark]],f[mark]));
- que[f[mark]]=;
- }
- }
- printf("%d\n",ans);
- return ;
- }
Codeforces 1059E. Split the Tree的更多相关文章
- Codeforces 461B. Appleman and Tree[树形DP 方案数]
B. Appleman and Tree time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- Codeforces 461B Appleman and Tree(木dp)
题目链接:Codeforces 461B Appleman and Tree 题目大意:一棵树,以0节点为根节点,给定每一个节点的父亲节点,以及每一个点的颜色(0表示白色,1表示黑色),切断这棵树的k ...
- [Split The Tree][dfs序+树状数组求区间数的种数]
Split The Tree 时间限制: 1 Sec 内存限制: 128 MB提交: 46 解决: 11[提交] [状态] [讨论版] [命题人:admin] 题目描述 You are given ...
- Codeforces 1129 E.Legendary Tree
Codeforces 1129 E.Legendary Tree 解题思路: 这题好厉害,我来复读一下官方题解,顺便补充几句. 首先,可以通过询问 \(n-1\) 次 \((S=\{1\},T=\{ ...
- Codeforces 280C Game on tree【概率DP】
Codeforces 280C Game on tree LINK 题目大意:给你一棵树,1号节点是根,每次等概率选择没有被染黑的一个节点染黑其所有子树中的节点,问染黑所有节点的期望次数 #inclu ...
- Split The Tree
Split The Tree 时间限制: 1 Sec 内存限制: 128 MB 题目描述 You are given a tree with n vertices, numbered from 1 ...
- [CodeForces1059E] Split the Tree
树形DP. 用倍增处理出来每个点往上能延伸出去的最远路径,nlogn 对于每个节点,如果它能被后代使用过的点覆盖,就直接覆盖,这个点就不使用,否则就ans++,让传的Max改成dp[x] #inclu ...
- Codeforces A. Game on Tree(期望dfs)
题目描述: Game on Tree time limit per test 1 second memory limit per test 256 megabytes input standard i ...
- 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 ...
随机推荐
- [Leetcode] Remove duplicates from sorted array 从已排序的数组中删除重复元素
Given a sorted array, remove the duplicates in place such that each element appear only once and ret ...
- 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 ...
- JAVA中string.replace()和string.replaceAll()的区别及用法
乍一看,字面上理解好像replace只替换第一个出现的字符(受javascript的影响),replaceall替换所有的字符,其实大不然,只是替换的用途不一样. public String r ...
- php魔术方法的使用
本文测试环境为 php5.5.12 一.__get .__set 将对象的属性进行接管. 一般来说,总是把类的属性定义为private,但是对属性的读取和赋值操作非常频繁,在php5+,预定义__se ...
- [POI2014] KUR-Couriers(洛谷P3567)
洛谷题目链接:[POI2014]KUR-Couriers 题目描述 Byteasar works for the BAJ company, which sells computer games. Th ...
- Ubuntu下kafka集群环境搭建及测试
kafka介绍: Kafka[1是一种高吞吐量[2] 的分布式发布订阅消息系统,有如下特性: 通过O(1)的磁盘数据结构提供消息的持久化,这种结构对于即使数以TB的消息存储也能够保持长时间的稳定性能 ...
- IntelliJ IDEA2017 + Tomcat 设置热部署
1.点击idea中tomcat设置 2.点击deployment查看Deploy at the server startup 中tomcat每次所运行的包是 xxxx:war 还是其他,如果是xxxx ...
- [bzoj3884]上帝与集合的正确用法——欧拉函数
题目大意 题解 出题人博客 代码 #include <bits/stdc++.h> using namespace std; const int M = 10001000; int phi ...
- Django【进阶】中间件
中间件 一.概念 django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法. 其 ...
- python3 面向对象、类、继承、组合、派生、接口、子类重用父类方法
对象是特征(变量)与技能(函数)的结合体而类是一系列对象共同的特征与技能的集合体 class teacher: lesson = "python" def __init__(sel ...