题意:给出一棵树,两个给给的人在第\(i\)天会从节点\(i\)沿着最长路径走,求最长的连续天数\([L,R]\)使得\([L,R]\)为起点的最长路径极差不超过m

求\(1\)到\(n\)的最长路经可用树形DP求解,

设\(f[i]\):\(i\)的子树下到\(i\)的最远距离

\(g[i]\):\(i\)子树下除了\(f[i]\)子树以外的最远距离

\(h[i]\):除了\(i\)子树以外到\(i\)的最远距离

\(h[i]\)从父到儿子的转移需要判断\(i\)到底是\(fa\)的最远距离所在边还是次远距离所在边(可相等),还有直接来自父亲以上\(h[fa]\)的转移

搞完后求极差就用二分+RMQ强行求出来,注意初始化需要f和h的对比

题目简单但要细心

#include<bits/stdc++.h>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define fastIO ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define println(x) printf("%lld\n",(ll)(x))
using namespace std;
typedef long long ll;
const int MAXN = 1e6+11;
const int MOD = 142857;
const int INF = 1<<30; int to[MAXN<<1],nxt[MAXN<<1],head[MAXN],tot;
int cost[MAXN<<1];
int n,m;
void init(int n){memset(head,-1,(n+2)*sizeof(int)),tot=0;}
void add(int u,int v,ll w){
to[tot]=v;
cost[tot]=w;
nxt[tot]=head[u];
head[u]=tot++;
}
int f[MAXN],g[MAXN],h[MAXN];
int mx[MAXN][22],mn[MAXN][22];
void DP0(int u,int fa){
f[u]=g[u]=h[u]=0;
for(int i=head[u];~i;i=nxt[i]){
int v=to[i]; ll w=cost[i];
if(v==fa) continue;
DP0(v,u);
if(f[v]+w>f[u]){
g[u]=f[u]; //次长子树
f[u]=f[v]+w; //最长子树
}else if(f[v]+w>g[u]){
g[u]=f[v]+w;
}
}
}
void DP1(int u,int fa){
for(int i=head[u];~i;i=nxt[i]){
int v=to[i]; ll w=cost[i];
if(v==fa) continue;
if(f[u]-w==f[v]) h[v]=max(h[u]+w,g[u]+w);//本身v作为儿子是f[u]的最大值,那就从u的次大子树中转移
else h[v]=max(h[u]+w,f[u]+w);
DP1(v,u);
}
}
ll C(int lo,int hi){
int k=log2(hi-lo+1);
return max(mx[lo][k],mx[hi-(1<<k)+1][k])
-min(mn[lo][k],mn[hi-(1<<k)+1][k]);
}
int gao(int st){
int lo=st,hi=n;
while(lo<hi){
int mid=lo+(hi-lo+1)/2;
if(C(st,mid)<=m) lo=mid;
else hi=mid-1;
}
return C(st,lo)?lo:lo-1;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("stdin.txt","r",stdin);
#endif
while(~scanf("%d%d",&n,&m)){
init(n);
for(int i=2;i<=n;i++){
int fi;ll di;
scanf("%d%lld",&fi,&di);
add(i,fi,di);
add(fi,i,di);
}
DP0(1,-1);
DP1(1,-1);
for(int i=1;i<=n;i++){
mx[i][0]=mn[i][0]=max(f[i],h[i]);//f[]只考虑子树内,h[]只考虑子树外
}
int t=log2(n);
for(int i=1;i<=t;i++){
for(int j=1;j<=n;j++){
mx[j][i]=max(mx[j][i-1],mx[j+(1<<i-1)][i-1]);
mn[j][i]=min(mn[j][i-1],mn[j+(1<<i-1)][i-1]);
}
}
int ans=0;
for(int i=1;i<=n;i++){
int hi=gao(i);
ans=max(ans,hi-i+1);
}
println(ans);
}
return 0;
}

BZOJ - 2500 树形DP乱搞的更多相关文章

  1. Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2)(A.暴力,B.优先队列,C.dp乱搞)

    A. Carrot Cakes time limit per test:1 second memory limit per test:256 megabytes input:standard inpu ...

  2. 2016 10 28考试 dp 乱搞 树状数组

    2016 10 28 考试 时间 7:50 AM to 11:15 AM 下载链接: 试题 考试包 这次考试对自己的表现非常不满意!! T1看出来是dp题目,但是在考试过程中并没有推出转移方程,考虑了 ...

  3. BZOJ 1040 树形DP+环套树

    就是有n个点n条边,那么有且只有一个环那么用Dfs把在环上的两个点找到.然后拆开,从这条个点分别作树形Dp即可. #include <cstdio> #include <cstrin ...

  4. BZOJ 4033 树形DP

    http://blog.csdn.net/mirrorgray/article/details/51123741 安利队长blog- 树形dp吧,状态挺显然的,dp[x][j]表示以x为根的子树中,选 ...

  5. BZOJ 4987 (树形DP)

    ###题面 https://www.lydsy.com/JudgeOnline/problem.php?id=4987 ###分析 先考虑贪心,显然k个节点形成一棵树 求出树的直径,显然直径应该只被经 ...

  6. bzoj 3573: [Hnoi2014]米特运输【树形dp+瞎搞】

    阅读理解题,题意是以1为根的有根树,每个点有点权,求修改最少点权能使每个点的权值等于其所有子节点权值之和并且每个点的所有子节点权值相等的个数 然后就比较简单了,就是有个技巧是数太大,需要对所有操作都取 ...

  7. HZOJ 20190727 T2 单(树上dp+乱搞?+乱推式子?+dfs?)

    考试T2,考试时想到了40pts解法,即对于求b数组,随便瞎搞一下就oxxk,求a的话,很明显的高斯消元,但考试时不会打+没开double挂成10pts(我真sb),感觉考试策略还是不够成熟,而且感觉 ...

  8. bzoj 2217 [Poi2011]Lollipop 乱搞 贪心

    2217: [Poi2011]Lollipop Time Limit: 15 Sec  Memory Limit: 64 MBSec  Special JudgeSubmit: 383  Solved ...

  9. [BZOJ4011][HNOI2015]落忆枫音-[dp乱搞+拓扑排序]

    Description 传送门 Solution 假如我们的图为DAG图,总方案数ans为每个点的入度In相乘(不算1号点).(等同于在每个点的入边选一条边,最后一定构成一棵树). 然而如果加了边x- ...

随机推荐

  1. Java 设计模式系列(一)单例模式

    Java 设计模式系列(一)单例模式 保证一个类只有一个实例,并且提供一个访可该实例的全局访问点. 一.懒汉式单例 /** * 懒汉式单例类:在第一次调用的时候实例化自己 * 1. 构造器私有化,避免 ...

  2. [GO]go使用contextCancel

    package main import ( "fmt" "context" ) func main() { gen := func(ctx context.Co ...

  3. 教你如何学python

    首先,你要有自信心,要明确学习目的.学Python,可以解决在软件使用中所遇到的问题,可以为找到理想工作添加重要砝码.还能锻炼思维,使我们的逻辑思维更加严密:能不断享受到创新的乐趣,将走在高科技的前沿 ...

  4. LUN

    1概念 LUN的全称是Logical Unit Number,也就是逻辑单元号.我们知道SCSI总线上可挂接的设备数量是有限的,一般为8个或者16个,我们可以用Target ID(也有称为SCSI I ...

  5. (转)JDBC模板类。

    Spring JDBC抽象框架core包提供了JDBC模板类,其中JdbcTemplate是core包的核心类,所以其他模板类都是基于它封装完成的,JDBC模板类是第一种工作模式. JdbcTempl ...

  6. TFS (Team Foundation Server) 2013集成Maven构建

    Team Foundation Server原生就支持跨平台的构建,包括Ant和Maven两种构建方式.通过配置构建服务器,连接TFS源代码库,可以实现持续集成构建,自动检测代码库健康状况,进而实现自 ...

  7. CodeIgniter使用中写的一些文章

    CI的captcha替代类库:  http://www.ifixedbug.com/posts/codeigniter-captcha-library 原生的captcha不是太好用,自己组装一个吧. ...

  8. JS三个编码函数和net编码System.Web.HttpUtility.UrlEncode比较

    JS三个编码函数和net编码比较 总结 1.escape.encodeUri.encodeUriComponent均不会对数字.字母进行编码.2.escape:对某些字符(如中文)进行unicode编 ...

  9. 从0开始学习Unity的学习笔记(I 界面学习和简单模型拼装)

    先给一个大致今天学习的图,然后后面是细节 1.下载Unity :官网下载需要版本 2.Unity安装:一定不要有中文路径:一台电脑可以安装不同版本的Unity,但是要安装在不同的文件夹下: 3. 新建 ...

  10. linux学习之用户的切换

    普通用户: 输入su 用户名,点击Enter Root用户: 输入su root,点击Enter 输入登录密码,点击Enter