BZOJ - 2500 树形DP乱搞
题意:给出一棵树,两个给给的人在第\(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乱搞的更多相关文章
- 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 ...
- 2016 10 28考试 dp 乱搞 树状数组
2016 10 28 考试 时间 7:50 AM to 11:15 AM 下载链接: 试题 考试包 这次考试对自己的表现非常不满意!! T1看出来是dp题目,但是在考试过程中并没有推出转移方程,考虑了 ...
- BZOJ 1040 树形DP+环套树
就是有n个点n条边,那么有且只有一个环那么用Dfs把在环上的两个点找到.然后拆开,从这条个点分别作树形Dp即可. #include <cstdio> #include <cstrin ...
- BZOJ 4033 树形DP
http://blog.csdn.net/mirrorgray/article/details/51123741 安利队长blog- 树形dp吧,状态挺显然的,dp[x][j]表示以x为根的子树中,选 ...
- BZOJ 4987 (树形DP)
###题面 https://www.lydsy.com/JudgeOnline/problem.php?id=4987 ###分析 先考虑贪心,显然k个节点形成一棵树 求出树的直径,显然直径应该只被经 ...
- bzoj 3573: [Hnoi2014]米特运输【树形dp+瞎搞】
阅读理解题,题意是以1为根的有根树,每个点有点权,求修改最少点权能使每个点的权值等于其所有子节点权值之和并且每个点的所有子节点权值相等的个数 然后就比较简单了,就是有个技巧是数太大,需要对所有操作都取 ...
- HZOJ 20190727 T2 单(树上dp+乱搞?+乱推式子?+dfs?)
考试T2,考试时想到了40pts解法,即对于求b数组,随便瞎搞一下就oxxk,求a的话,很明显的高斯消元,但考试时不会打+没开double挂成10pts(我真sb),感觉考试策略还是不够成熟,而且感觉 ...
- bzoj 2217 [Poi2011]Lollipop 乱搞 贪心
2217: [Poi2011]Lollipop Time Limit: 15 Sec Memory Limit: 64 MBSec Special JudgeSubmit: 383 Solved ...
- [BZOJ4011][HNOI2015]落忆枫音-[dp乱搞+拓扑排序]
Description 传送门 Solution 假如我们的图为DAG图,总方案数ans为每个点的入度In相乘(不算1号点).(等同于在每个点的入边选一条边,最后一定构成一棵树). 然而如果加了边x- ...
随机推荐
- Basic4android v3.20 发布
这次主要是可视化设计器的增强. 具体新功能如下: This version includes many important improvements: Visual designer Anchors ...
- mongo学习- 副本集 大多数原则
副本集中有一个重要的概念“大多数”,意思是说,选择主节点需要大多数决定(本人亲自做了实验) 步骤: 1.开启副本集(如果没有配置好 副本集的 亲参考我的上篇文章 https://www.cnblog ...
- Requests接口测试-对cookies的操作处理(一)
大家都对cookie都不陌生,我们本篇文章使用requests结合cookie进行实例演示.我们使用一个接口项目地址,因为接口项目涉及到隐私问题,所以这里接口的地址我暂时不会给大家开放,但是我会给大家 ...
- ADO.net开放式并发
https://docs.microsoft.com/zh-cn/dotnet/framework/data/adonet/optimistic-concurrency 在多用户环境中,有两种用于更新 ...
- Tomcat的windows10集群搭建(一台电脑同时运行多个tomcat配置方法)
配置方法(好久不配置了,忘记了,今天还是总结下吧): 1.官网下载tomcat ,我下载了tomcat6.0和tomcat7.0(以便区分) 官网地址:http://tomcat.apache.org ...
- C++创建自己的库文件(dll文件创建和编译)
创建编译库文件有个好处就是不容易被修改,加密的,方便调用,但是缺点是不容易查看其中的内容,反编译比较麻烦.下面让我们使用VC创建编译自己的库文件吧.常用的函数,不常更改的,应该放到库文件里,所以库文件 ...
- BI使用者的角色
把企业中的BI使用者的角色分成如下几类: 系统管理员:没有数据权限:没有功能权限:负责配置其他人的权限:BI专家:拥有所有数据权限:拥有多维分析,报表查看,报表开发,模型开发权限:负责开发和维护BI系 ...
- Javascript Object.defineProperty()
转载声明: 本文标题:Javascript Object.defineProperty() 本文链接:http://www.zuojj.com/archives/994.html,转载请注明转自Ben ...
- Linux TCP不同状态的连接数统计
方法一:利用netstat命令 统计 TIME_WAIT/CLOSE_WAIT/ESTABLISHED/LISTEN 等TCP状态的连接数 netstat -tan |grep ^tcp |awk ' ...
- awk中NF的使用
统计机器中网络连接各个状态个数 netstat -a | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' 一下子不明白$NF是什么意 ...