luogu P5558 心上秋
LINK:心上秋
唐多令 宋 吴文英
何处合成愁。离人心上秋。纵芭蕉,不雨也飕飕。都道晚凉天气好,有明月,怕登楼。
年事梦中休。花空烟水流。燕辞归,客尚淹留。垂柳不萦裙带住。漫长是,系行舟。
心上秋 笔下梅 笙中月。
此题 求树上任意两点之间的最长不下降子序列 权值集合为{1~5}.
\(n<=30000,m<=300000\)
考虑暴力 把链抽出来然后暴力dp.最长不下降子序列的dp是nlogn的 所以总复杂度为nlognm.
优化暴力 发现权值集合很小 把链抽出来之后 设f[i][j]表示到达第i个点权值为j的最长长度 多了一个五倍的常数不过复杂度O(n) 总复杂度nm.
考虑优化 如果权值集合只有1,2怎么办?
不妨考虑倍增 设f[i][j][k][w]表示从i跳到2^j的祖先经过的边的权值从k到w的最长不降子序列的长度。
发现这个东西可以合并.
对于所有数据我们可以倍增预处理出这个数组。
对于某个询问(x,y) 我们先让x调到lca累计一个数组g[k]表示小于等于k的路径的最长长度 然后再从lca跳到y即可。
跟保卫王国的倍增dp有点像 不过我没写过那道题的倍增dp 回来可以看一下 值得一提的是这道题没有修改 所以就简单了很多。
我觉得树剖不太能写的样子 矩阵不是很好维护.
我写的有点繁琐了。大体上有一个坑点:注意g数组的维护要维护某个区间的答案 初始化和转移要注意。
在最后求答案的时候也注意由lca跳向y的时候要反着做. 数组下标也得反着.所以g数组也要有一个反着的值.
通过这道题 我们发现可以扩展到序列上 如求某段序列的最长不下降子序列 也可以使用这种倍增的方法来做。
可见倍增是优化dp的一种常用手段。
const int MAXN=30010;
int n,m,len,maxx,ans;
int ql[MAXN],qr[MAXN],wl[MAXN],wr[MAXN],top1,top2;
int g[MAXN][16][6][6],f[MAXN][16],Log[MAXN],d[MAXN],w[MAXN][6];
int lin[MAXN],ver[MAXN<<1],nex[MAXN<<1],e[MAXN<<1];
inline void add(int x,int y,int z)
{
ver[++len]=y;
nex[len]=lin[x];
lin[x]=len;
e[len]=z;
}
inline void dfs(int x,int father)
{
d[x]=d[father]+1;
f[x][0]=father;
rep(1,Log[d[x]],i)
{
f[x][i]=f[f[x][i-1]][i-1];
rep(1,maxx,k)
rep(1,maxx,w)
{
int s1=min(k,w),s2=max(k,w);
rep(s1,s2,l)g[x][i][k][w]=max(g[x][i][k][w],g[x][i-1][k][l]+g[f[x][i-1]][i-1][l][w]);
}
}
go(x)
{
if(tn==father)continue;
rep(e[i],maxx,j)rep(1,e[i],k)g[tn][0][j][k]=g[tn][0][k][j]=1;
dfs(tn,x);
}
}
inline void LCA(int x,int y)
{
top1=top2=0;
if(d[x]>d[y])
{
fep(Log[d[x]],0,i)
{
if(d[f[x][i]]>=d[y])
{
ql[++top1]=x;
wl[top1]=i;
x=f[x][i];
}
}
}
if(d[y]>d[x])
{
fep(Log[d[y]],0,i)
{
if(d[f[y][i]]>=d[x])
{
qr[++top2]=y;
wr[top2]=i;
y=f[y][i];
}
}
}
if(x==y)return;
fep(Log[d[x]],0,i)
{
if(f[x][i]!=f[y][i])
{
ql[++top1]=x;
wl[top1]=i;
x=f[x][i];
qr[++top2]=y;
wr[top2]=i;
y=f[y][i];
}
}
ql[++top1]=x;
wl[top1]=0;
qr[++top2]=y;
wr[top2]=0;
}
inline void get_ans()
{
ans=0;
rep(1,top1,i)
{
rep(1,maxx,j)w[i][j]=0;
rep(1,maxx,j)
rep(1,j,k)w[i][j]=max(w[i][j],w[i-1][k]+g[ql[i]][wl[i]][k][j]);
}
int l=top2;
rep(top1+1,top2+top1,i)
{
rep(1,maxx,j)w[i][j]=0;
rep(1,maxx,j)
rep(1,j,k)w[i][j]=max(w[i][j],w[i-1][k]+g[qr[l]][wr[l]][j][k]);
--l;
}
rep(1,maxx,i)ans=max(ans,w[top1+top2][i]);
}
int main()
{
freopen("1.in","r",stdin);
get(n);
rep(2,n,i)
{
int x,y,z;
get(x);get(y);get(z);
maxx=max(maxx,z);
add(x,y,z);add(y,x,z);
Log[i]=Log[i>>1]+1;
}
dfs(1,0);
get(m);
rep(1,m,i)
{
int x,y;
get(x);get(y);
LCA(x,y);
get_ans();
put(ans);
}
return 0;
}
luogu P5558 心上秋的更多相关文章
- CTYZ的树论赛(P5557 旅行/P5558 心上秋/P5559 失昼城的守星使)
总结 由于受中秋节影响,没能在比赛时间内切掉\(T3\) 思维难度\(T1<T2<T3\),代码难度\(T1>T2>T3\) P5557 旅行 显然跳到环上去后就可以直接模了, ...
- [Luogu] P4910 帕秋莉的手环
题目背景 帕秋莉是蕾米莉亚很早结识的朋友,现在住在红魔馆地下的大图书馆里.不仅擅长许多魔法,还每天都会开发出新的魔法.只是身体比较弱,因为哮喘,会在咏唱符卡时遇到麻烦. 她所用的属性魔法,主要是生命和 ...
- 【题解】Luogu P4910 帕秋莉的手环
原题传送门 "连续的两个中至少有1个金的"珂以理解为"不能有两个木相连" 我们考虑一个一个将元素加入手环 设f\([i][0/1]\)表示长度为\(i\)手环末 ...
- mysql面试常见题目3
三十六大 冯唐 春水初生, 春林初盛, 春风十里,不如你. 秋风落叶, 秋雨绵绵, 愁心上秋,只为你. 某个员工信息表结构和数据如下: id name dept salary edlevel hire ...
- 算法是什么我记不住,But i do it my way. 解一道滴滴出行秋招编程题。
只因在今日头条刷到一篇文章,我就这样伤害我自己,手贱. 刷头条看到一篇文章写的滴滴出行2017秋招编程题,后来发现原文在这里http://www.cnblogs.com/SHERO-Vae/p/588 ...
- win7系统下的飞秋发送文件失败问题
飞秋发送文件失败这个问题大多数是由防火墙引起的1.检查windows自带的防火墙设置,在左侧的"允许程序通过windows防火墙"查看飞秋是否存在,不存在则增加之,公网.专网都勾选 ...
- Luogu 魔法学院杯-第二弹(萌新的第一法blog)
虽然有点久远 还是放一下吧. 传送门:https://www.luogu.org/contest/show?tid=754 第一题 沉迷游戏,伤感情 #include <queue> ...
- luogu p1268 树的重量——构造,真正考验编程能力
题目链接:http://www.luogu.org/problem/show?pid=1268#sub -------- 这道题费了我不少心思= =其实思路和标称毫无差别,但是由于不习惯ACM风格的题 ...
- wireshake抓包,飞秋发送信息,python
http://wenku.baidu.com/link?url=Xze_JY8T15pqI9mBLRpTxWF2d6MP-32xb6UwuE6tsUmitRDheJe-Ju87WlDEDBGuI5MF ...
随机推荐
- P1330 封锁阳光大学——深度优先搜索DFS
P1330 封锁阳光大学 题目描述 曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街.河蟹看到欢快的曹,感到不爽.河蟹决定封锁阳光大学,不让曹刷街. 阳光大学的校园是一张由 \(n ...
- [POJ3977] Subet(二分枚举)
解题报告 前置知识:折半查找法(二分法) 顾名思义,折半就是把一组数据(有序)分成两半,判断我们要找的key值在哪一半当中,不断重复该操作直至找到目标key值,这玩意说白了就是二分的另一个名字. 解决 ...
- Jenkins Pipeline 部署 SpringBoot 应用
一. 安装依赖包 yum install -y wget yum install -y gcc-c++ yum install -y zlib-devel perl-ExtUtils-MakeMake ...
- STL测试3)优先级队列实现二叉堆
用法: big_heap.empty();判断堆是否为空 big_heap.pop();弹出栈顶元素最大值 big_heap.push(x);将x添加到最大堆 big_heap.top();返回栈顶元 ...
- 云小课 | “VPC连接”知多少
摘要:华为云提供了丰富的网络服务,可满足多种网络互连场景. 同Region的两个VPC怎么连通?” “跨Region的两个VPC又怎么连通?” “VPC内的ECS搭建了一个应用,需要访问Interne ...
- MySQL入门(引擎、数据类型、约束)
MySQL入门(二) 表的引擎:驱动数据的方式 - 数据库优化 # 概要:引擎是建表规定的,提供给表使用,不是数据库的 # 展示所有引擎 show engines; # innodb(默认): 支持事 ...
- java 基础(三) 搭建Java编译环境(树莓派)
安装需求1.JDK的安装2.PI4J的安装 JDK的安装1.首先到JDK的官网:https://www.oracle.com/technetwork/java/javase/downloads/ind ...
- 数据可视化之分析篇(八)Power BI数据分析应用:结构百分比分析法
https://zhuanlan.zhihu.com/p/113113765 PowerBI数据分析02:结构百分比分析法 作者:海艳 结构百分比分析法,又称纵向分析,是指同一期间财务报表中不同项目间 ...
- Configurate root account
After having installed Ubuntu OS, you should update config file for root account. The commands are l ...
- 开会时CPU 飙升100%同事们都手忙脚乱记一次应急处理过程
告警 正在开会,突然钉钉告警声响个不停,同时市场人员反馈客户在投诉系统登不进了,报504错误.查看钉钉上的告警信息,几台业务服务器节点全部报CPU超过告警阈值,达100%. 赶紧从会上下来,SSH登录 ...