P4309 [TJOI2013]最长上升子序列 平衡树 + dp
传送门
文章目录
- 题意:
- 思路:
题意:
思路:
注意到一个很关键的条件,每次插入iii,而iii是递增的,也就是说插入iii之后只会从前面的最大值转移过来,所以我们现在只需要维护插入操作即可,这个显然可以用平衡树来维护。
让后就是一个裸的fhq−treapfhq-treapfhq−treap了,我们需要维护一个dpdpdp数组,dp[i]dp[i]dp[i]表示以iii个数结尾的最长上升子序列,对于平衡树中的每个节点都维护一个他的位置pospospos,当pushuppushuppushup的时候max(dp[tr[u].pos],max(tr[tr[u].l].val,tr[tr[u].r].val))max(dp[tr[u].pos],max(tr[tr[u].l].val,tr[tr[u].r].val))max(dp[tr[u].pos],max(tr[tr[u].l].val,tr[tr[u].r].val))转移即可。注意dp[tr[u].pos]dp[tr[u].pos]dp[tr[u].pos]不能用tr[u].valtr[u].valtr[u].val代替,因为他的值在子树分裂之前存的是子树中最大值,分裂后不一定是这个,有可能变小,所以需要一个dpdpdp数组存下来当前位置的答案。
附带debugdebugdebug代码。
// Problem: P4309 [TJOI2013]最长上升子序列
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4309
// Memory Limit: 125 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)//#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
//#pragma GCC optimize(2)
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid (tr[u].l+tr[u].r>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std;//void rd_cre() { freopen("d://dp//data.txt","w",stdout); srand(time(NULL)); }
//void rd_ac() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//AC.txt","w",stdout); }
//void rd_wa() { freopen("d://dp//data.txt","r",stdin); freopen("d://dp//WA.txt","w",stdout); }typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;const int N=1000010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;int n,root,x,y,z;
int tot;
int dp[N];
struct Node {int l,r;int id,size,rank,fa,val;int pos;
}tr[N];void pushup(int u) {tr[u].size=tr[tr[u].l].size+tr[tr[u].r].size+1;tr[u].val=max(dp[tr[u].pos],max(tr[tr[u].l].val,tr[tr[u].r].val));
}int newnode(int v,int i) {int u=++tot;tr[u].l=tr[u].r=0;tr[u].rank=rand(); tr[u].size=1;tr[u].val=v;tr[u].pos=i;dp[i]=v;return u;
}void split(int u,int k,int &x,int &y) {if(!u) { x=y=0; return; }if(k<=tr[tr[u].l].size) y=u,split(tr[u].l,k,x,tr[u].l);else x=u,split(tr[u].r,k-tr[tr[u].l].size-1,tr[u].r,y);pushup(u);
}int merge(int u,int v) {if(!u||!v) return v+u;if(tr[u].rank<tr[v].rank) {tr[u].r=merge(tr[u].r,v);pushup(u);return u;}else {tr[v].l=merge(u,tr[v].l);pushup(v);return v;}
}void dfs(int u) {if(!u) return;dfs(tr[u].l);printf("%d %d\n",u,tr[u].val);dfs(tr[u].r);
}int main()
{// ios::sync_with_stdio(false);
// cin.tie(0);scanf("%d",&n);for(int i=1;i<=n;i++) {int pos; scanf("%d",&pos); split(root,pos,x,y);int val=tr[x].val;//cout<<i<<' '<<val<<endl;//cout<<"**"<<i<<' '<<val<<endl;//dfs(x);root=merge(merge(x,newnode(val+1,i)),y);printf("%d\n",tr[root].val);//db;}return 0;
}
/**/
P4309 [TJOI2013]最长上升子序列 平衡树 + dp相关推荐
- BZOJ 3173: [Tjoi2013]最长上升子序列
3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1524 Solved: 797 [Submit][ ...
- BZOJ3173 [TJOI2013]最长上升子序列
题面: 3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 2108 Solved: 1067 [Sub ...
- [BZOJ]3173: [Tjoi2013]最长上升子序列
题解: 考虑按照元素升序加入 所以对位置在其后的元素LIS无影响 然后从前面位置的最大值转移过来就行 ,,,,平衡树无脑模拟 #include <algorithm> #includ ...
- [TJOI2013]最长上升子序列
[TJOI2013]最长上升子序列 题目大意: 给定一个序列,初始为空.将\(1\sim n(n\le10^5)\)的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字后输出LIS长 ...
- [BZOJ3173][Tjoi2013]最长上升子序列
[BZOJ3173][Tjoi2013]最长上升子序列 试题描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上 ...
- bzoj 3173: [Tjoi2013]最长上升子序列(离线二分+树状数组)
3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 2051 Solved: 1041 [Submit] ...
- 【bzoj 3173】[Tjoi2013]最长上升子序列
Description 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? Input 第一行一 ...
- leetcode 583. Delete Operation for Two Strings | 583. 两个字符串的删除操作(最长公共子序列,DP)
题目 https://leetcode.com/problems/delete-operation-for-two-strings/ 题解 本题实质上是个最长公共子序列问题,又是经典的 递归-> ...
- leetcode 1143. 最长公共子序列(dp)
给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度.如果不存在 公共子序列 ,返回 0 . 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符 ...
最新文章
- 【从零开始的ROS四轴机械臂控制】(三) - 为机械臂添加摄像头和夹爪、解决gazebo模型抖动、使用gazebo建立sdf模型
- 携程用的什么地图_2020什么项目最值得投资
- 【小程序开发者专享】腾讯云联手多家科技企业,聚焦小程序·云开发实践!...
- 四则运算2+psp0
- REMarkerClusterer
- python中错误和异常处理
- linux上samba+本地yum源最简单的配置
- 【渝粤教育】国家开放大学2018年春季 0605-22T中国古代文学(2) 参考试题
- 资产管理软件 GLPI的安装(转)
- 饿了么商品排序怎么实现PHP,PHP实现桶排序算法
- afuwin64教程_AMI刷BIOS工具下载|AFUWIN(AMI刷BIOS工具) v4.47官方最新版 附使用教程_星星软件园...
- 利用Python分析新旧页面的A/B测试结果
- 解决OSS传输的文本文件网页打开乱码
- LLC谐振变换器学习 一
- 网易我的世界服务器看不到聊天信息,网易禁止文字?我的世界:文字消失“不可逆”的6种解决办法...
- 规则引擎 Drools--决策表(Decision Table)使用简介
- 海思Hi3516CV500/Hi3516DV300处理参数比较
- 相机计算坐标公式_相机采样点的坐标转换方法与流程
- Esp8266 进阶之路20 【高级篇】深入学习esp8266的esp now模式组网,仿机智云做一个小网关,实现无需网络下轻松彼此连接通讯交互数据。(附带Demo)
- iOS 热更新/热修复
热门文章
- python获取键盘事件_50-用Python监听鼠标和键盘事件
- 左手菲尔兹右手突破奖,这个中国女婿其实是英国贵族?拿到300万奖金后他这样说……...
- Excel有哪些需要熟练掌握而很多人不会的技能!
- 网易10万+课程迅速刷屏又迅速被封:“违规”背后的思考
- android activity解耦,Android与设计模式:用单一职责原则为Activity解耦
- float型y取值在1.0c语言表达式,2011年全国计算机二级C语言模拟试题及答案(14)...
- mysql批量条件字段_mysql批量更新多条记录的同一个字段为不同值的方法
- 微型计算机c560,2010广东省计算机等级考试试题 二级C试题最新考试试题库
- java定时器报错,定时器设置报错
- 简述原型模型的特点_3D打印硅胶复模手板的步骤和特点有哪些