题面

清橙

Sol

一种新的树上\(DP\)姿势

从左往右按链\(DP\)

做法:

维护两个栈\(S1\),\(S2\)

\(S1\)存当前的链

\(S2\)存分叉点以下要改的链

\(Dfs\),弄一个分叉点,之前的链经过它,并且另一条要转移到的链也经过它

那么每次在叶节点时就把\(S1\)最下面的一部分变成\(S2\)

转移

两种情况:

最大值在\(S1\)和在\(S2\)的情况

那么枚举\(S2\),\(S1\)中小于\(S2\)的枚举的值的点就可以转移,并维护\(S1\),\(S2\)的前缀最大值

再枚举\(S2\),利用前缀最大值,\(S1\)的大于等于\(S2\)的转移

# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
# define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
using namespace std;
typedef long long ll;
const int _(1e5 + 5); IL int Input(){
RG int x = 0, z = 1; RG char c = getchar();
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
} int n, val[_], f[_], ans = -2e9;
int fa[_], S1[_], S2[_], id[_], maxv[_];
vector <int> edge[_]; IL void Dfs(RG int u, RG int top){ //top是分叉点在S1中的位置
if(!top) S1[++S1[0]] = u, id[u] = S1[0], f[u] = val[u]; //初始第一条链
RG int l = edge[u].size();
if(l){ //非叶子节点不做更新
for(RG int i = 0; i < l; ++i){
RG int v = edge[u][i];
if(!i){ //最左边的直接加入S2
if(top) S2[++S2[0]] = v;
Dfs(v, top);
}
else S2[S2[0] = 1] = v, Dfs(v, id[u]); //新开一条链
}
return;
}
if(!top) return;
RG int mx1 = val[S1[top]], maxf = ans, now = top, mx2 = mx1;
for(RG int i = 1; i <= S2[0]; ++i){ //最大值在S2中的情况
while(now < S1[0] && val[S1[now]] <= mx1){ //计算每个最大值的贡献
mx2 = max(mx2, val[S1[now]]);
maxf = max(maxf, f[S1[++now]]);
maxv[S1[now]] = mx2; //维护S1前缀最大值
}
f[S2[i]] = maxf - mx1; //转移
maxv[S2[i]] = mx1; //维护S2前缀最大值
mx1 = max(mx1, val[S2[i]]); //下一个点
}
while(now < S1[0]){ //处理剩下的
mx2 = max(mx2, val[S1[now]]);
maxv[S1[++now]] = mx2;
}
maxf = ans, now = S1[0];
for(RG int i = S2[0]; i; --i){ //最大值在S1中的情况
while(now > top && maxv[S1[now]] >= maxv[S2[i]]){
maxf = max(maxf, f[S1[now]] - maxv[S1[now]]);
--now;
}
f[S2[i]] = max(f[S2[i]], maxf);
}
for(RG int i = 1; i <= S2[0]; ++i){ //更新到下一条链
f[S2[i]] += val[S2[i]];
S1[top + i] = S2[i];
id[S2[i]] = top + i;
}
S1[0] = top + S2[0];
} int main(RG int argc, RG char* argv[]){
File("cut");
n = Input(), Fill(f, -127);
for(RG int i = 1, t; i <= n; ++i){
val[i] = Input(), t = Input();
for(RG int j = 1, tt; j <= t; ++j)
tt = Input(), edge[i].push_back(tt);
}
Dfs(1, 0);
for(RG int i = 1; i <= S1[0]; ++i) ans = max(ans, f[S1[i]]);
printf("%d\n", ans);
return 0;
}

清橙A1212:剪枝的更多相关文章

  1. 清橙A1202&Bzoj2201:彩色圆环

    因为Bzoj是权限题,所以可以去清橙做一下 Sol 突然考了一道这样的题,考场上强行\(yy\)出来了 win下评测Long double爆零TAT 首先肯定是破环为链变成序列问题辣 那么就要求第一个 ...

  2. [清橙A1210]光棱坦克

    [清橙A1210]光棱坦克 题目大意: 平面上放置了\(n(n\le7000)\)个反射装置,光纤将从某个装置出发,在经过一处装置时发生反射,若经过的装置坐标依次为\((x_1,y_1),(x_2,y ...

  3. 清橙A1206.小Z的袜子 && CF 86D(莫队两题)

    清橙A1206.小Z的袜子 && CF 86D(莫队两题) 在网上看了一些别人写的关于莫队算法的介绍,我认为,莫队与其说是一种算法,不如说是一种思想,他通过先分块再排序来优化离线查询问 ...

  4. 洛谷 P1903 BZOJ 2120 清橙 A1274【模板】分块/带修改莫队(数颜色)(周奕超)

    试题来源 2011中国国家集训队命题答辩 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会像你发布如下指令: 1. Q L R代表询问你从第L支画笔 ...

  5. 清橙 A1206 小Z的袜子(莫队算法)

    A1206. 小Z的袜子 时间限制:1.0s   内存限制:512.0MB   总提交次数:1357   AC次数:406   平均分:46.75   将本题分享到:        查看未格式化的试题 ...

  6. 清橙A1363. 水位 - 清华大学2012年信息学优秀高中学子夏令营

    问题描述 有一个正方形的地区,该地区特点鲜明:如果把它等分为N×N个小正方形格子的话,在每个格子内的任意地点的地表高度是相同的,并且是一个0到M之间的整数.正方形地区的外部被无限高的边界包围. 该地区 ...

  7. 清橙 A1120 拦截导弹 -- 动态规划(最长上升子序列)

    题目地址:http://oj.tsinsen.com/A1120 问题描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但 ...

  8. 清橙OJ 1082 查找第K小元素 -- 快速排序

    题目地址:http://oj.tsinsen.com/A1082 问题描述 给定一个大小为n的数组s和一个整数K,请找出数组中的第K小元素. 这是一个补充程序的试题,你需要完成一个函数: int fi ...

  9. 【清橙A1094】【牛顿迭代法】牛顿迭代法求方程的根

    问题描述 给定三次函数f(x)=ax3+bx2+cx+d的4个系数a,b,c,d,以及一个数z,请用牛顿迭代法求出函数f(x)=0在z附近的根,并给出迭代所需要次数. 牛顿迭代法的原理如下(参考下图) ...

随机推荐

  1. jenkins中使用rsync, scp命令

    jenkins 中使用 rsync 命令 是出现一些错误输出 Host key verification failed. rsync: connection unexpectedly closed ( ...

  2. Linux下绝对经典的命令

    1.使用远程终端时,可以使用如下命令: screen tmux 2.下载文件可以使用如下命令: curl wget 3.压缩解压缩可以使用: tar .zip.rar 4.使用抓包工具 tcpdump ...

  3. docker swarm集群搭建

    本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 摘要: swarm是docker原生的集群管理软件,与kuberne ...

  4. Java经典编程题50道之十一

    有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? public class Example11 { public static void main(String[] arg ...

  5. Visual Studio 2017 Enterprise 发布 15.3.3 版,附离线安装包百度网盘下载。

    Visual Studio 2017 Enterprise 发布 15.3.3 版,附离线安装包百度网盘下载. Visual Studio 2017 Enterprise 更新至 15.3.3 ,本安 ...

  6. angular4升级angular5问题记录之this.location.back()

    在之前的项目中,导航回上一个路由采用注入的Location服务,利用浏览器的历史堆栈,导航到上一步. 官方文档也就是这么写的 而然在升级到5.2的版本的时候,在浏览器运行的时候并没有什么问题,在项目打 ...

  7. Centos下安装Lamp和vsftpd、redis

    yum安装httpd和php.mysql服务 yum search httpd //搜索httpd开头的软件包 yum install httpd.x86_64 //找到apache 对应的软件包名 ...

  8. 剑指offer第五天

    28.数组中出现次数超过一半的数字 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字.例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}.由于数字2在数组中出现了5次,超过数 ...

  9. 《设计模式之禅》--备忘录扩展:clone方式的备忘录

    接上篇<设计模式之禅>--策略扩展:策略枚举 需求:使用clone方式实现备忘录模式 发起人角色 public class Originator implements Cloneable ...

  10. WPF文本框只允许输入数字

    XAML代码   < TextBox Height="23" HorizontalAlignment="Left" Margin="100,5, ...