BZOJ 3173: [Tjoi2013]最长上升子序列
3173: [Tjoi2013]最长上升子序列
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 1524 Solved: 797
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
0 0 2
Sample Output
1
2
HINT
100%的数据 n<=100000
Source
分析
本来是想找Treap的练手题,考完NOIP放松一下心情的,结果看完题发现根本不用Treap……
首先,因为加入的元素是越来越大的,所以每次加入之后对于后面的元素的LIS的DP值(即以其结尾的最长上升子序列长度)不会改变,而前面的更不会改变。也就是说,最终序列的DP数组就是逐步加入的DP值了。所以只需要想方设法求出最终序列,再做一遍O(NlogN)的LIS问题即可。
求解最终的序列方法多种多样,可以用Treap暴力维护插入操作,也可以逆着推出最终的序列,我选择了后者。
对于第N个插入的元素,其插入的位置就是最终的位置。当它找到了最终位置之后,就把那个位置改为空。类似的,每个元素的最终位置,就是此时的第Xk个非空位置。这个操作用线段树维护即可轻松做到O(logN),当然也可以树状数组+二分做到O(log^2N),常数小也许跑得反而更快,(lll¬ω¬)。
代码
#include <bits/stdc++.h> using namespace std; #define low lower_bound
#define upp upper_bound const int N = ;
const int inf = 0x3f3f3f3f; int n;
int pos[N];
int num[N];
int ans[N];
int stk[N]; struct node
{
int lt, rt, sum; node (void) :
lt (), rt (), sum () {};
}; node tree[N << ]; void build (int p, int l, int r)
{
node &t = tree[p]; t.lt = l;
t.rt = r; t.sum = r - l + ; if (l != r)
{
int mid = (l + r) >> ; build (p << , l, mid);
build (p << | , mid + , r);
}
} void change (int p, int pos, int val)
{
node &t = tree[p]; if (t.lt != t.rt)
{
int mid = (t.lt + t.rt) >> ; if (pos <= mid)
change (p << , pos, val);
else
change (p << | , pos, val); t.sum = tree[p << ].sum + tree[p << | ].sum;
}
else
t.sum = val;
} int query (int p, int val)
{
node &t = tree[p]; if (t.lt != t.rt)
{
int tmp = tree[p << ].sum; if (val <= tmp)
return query (p << , val);
else
return query (p << | , val - tmp);
}
else
return t.lt;
} signed main (void)
{
scanf ("%d", &n); for (int i = ; i <= n; ++i)
scanf ("%d", pos + i); build (, , n); for (int i = n; i >= ; --i)
{
int t = query (, pos[i] + );
num[t] = i, change (, t, );
} memset (stk, inf, sizeof(stk)); for (int i = ; i <= n; ++i)
{
*low (stk, stk + i, num[i]) = num[i];
ans[num[i]] = low (stk, stk + i, num[i]) - stk;
} for (int i = ; i <= n; ++i)
ans[i] = max (ans[i], ans[i - ]); for (int i = ; i <= n; ++i)
printf ("%d\n", ans[i] + );
}
BZOJ_3173.cpp
后记:
大概是刚考完NOIP,又要准备学考,大家的刷题兴致不高啊,居然被我轻松拿了Day榜,(*^_^*)/。
| No. | User | Nick Name | AC | Submit | Ratio |
| 1 | YOUSIKI | ねえ、あなたは知っていますか、桜の行方の速度は秒速5センチメートル | 5 | 6 | 83.333% |
@Author: YouSiki
BZOJ 3173: [Tjoi2013]最长上升子序列的更多相关文章
- Bzoj 3173: [Tjoi2013]最长上升子序列 平衡树,Treap,二分,树的序遍历
3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1183 Solved: 610[Submit][St ...
- BZOJ 3173: [Tjoi2013]最长上升子序列( BST + LIS )
因为是从1~n插入的, 慢插入的对之前的没有影响, 所以我们可以用平衡树维护, 弄出最后的序列然后跑LIS就OK了 O(nlogn) --------------------------------- ...
- BZOJ 3173: [Tjoi2013]最长上升子序列 [splay DP]
3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1613 Solved: 839[Submit][St ...
- bzoj 3173 [Tjoi2013]最长上升子序列 (treap模拟+lis)
[Tjoi2013]最长上升子序列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2213 Solved: 1119[Submit][Status] ...
- BZOJ 3173 [Tjoi2013] 最长上升子序列 解题报告
这个题感觉比较简单,但却比较容易想残.. 我不会用树状数组求这个原排列,于是我只好用线段树...毕竟 Gromah 果弱马. 我们可以直接依次求出原排列的元素,每次找到最小并且最靠右的那个元素,假设这 ...
- BZOJ 3173: [Tjoi2013]最长上升子序列 (线段树+BIT)
先用线段树预处理出每个数最终的位置.然后用BIT维护最长上升子序列就行了. 用线段树O(nlogn)O(nlogn)O(nlogn)预处理就直接倒着做,每次删去对应位置的数.具体看代码 CODE #i ...
- bzoj 3173: [Tjoi2013]最长上升子序列【dp+线段树】
我也不知道为什么把题看成以插入点为结尾的最长生生子序列--还WA了好几次 先把这个序列最后的样子求出来,具体就是倒着做,用线段树维护点数,最开始所有点都是1,然后线段树上二分找到当前数的位置,把这个点 ...
- BZOJ 3173: [Tjoi2013]最长上升子序列 Splay
一眼切~ 重点是按照 $1$~$n$ 的顺序插入每一个数,这样的话就简单了. #include <cstdio> #include <algorithm> #define N ...
- 3173: [Tjoi2013]最长上升子序列
原题:http://www.lydsy.com/JudgeOnline/problem.php?id=3173 题解:促使我写这题的动力是,为什么百度遍地是Treap,黑人问号??? 这题可以用线段树 ...
随机推荐
- sublime自定义快键键不行,
其实sublime自身就有格式化命令,就不再安装插件,位置在[Edit]->[Line]->[Reindent]但这个默认的命令没有快捷键,就重新定义了一下,想用习惯了的eclipse快捷 ...
- CGI、FastCGI和PHP-FPM关系图解
CGI.FastCGI和PHP-FPM关系图解 webapp即是php解析器等 当Web Server收到 index.php 这个请求后,会启动对应的 CGI 程序,这里就是PHP的解析器.接下 ...
- Asp.Net Core-几行代码解决Razor中的嵌套if语句
MVC开发中,经常会遇到在razor中插入简单的逻辑判断. @if (clientManager.IsAdmin) { if (!Model.Topic.Top) { <a asp-action ...
- 最佳实践 —— 详细谈谈如何减小APK体积
转载请注明出处: http://www.cnblogs.com/soaringEveryday/p/5254520.html 随着Android移动开发的需求越来越复杂,我们不可避免的遇到发布出去的a ...
- java并发:同步容器&并发容器
第一节 同步容器.并发容器 1.简述同步容器与并发容器 在Java并发编程中,经常听到同步容器.并发容器之说,那什么是同步容器与并发容器呢?同步容器可以简单地理解为通过synchronized来实现同 ...
- .net异步编程
现在电脑大部分都是多核心,在处理多线程方便有很大优势,异步调用方法的时候可以立即返回执行其他程序,进行异步编程会让程序运行效率更高. 我也是刚刚关注异步编程方面知识,也有很多不是很理解,所以想向大神请 ...
- web安全——目录
说明 写这个目录是为了方便阅读.也是为了记录统一的问题. 这个系列,并不一定是全的,也不一定是对的,所以请大家多做过滤. 这里面场景比较多的是本人在实践中遇到的问题,然后自己思考抽象的. 目录 web ...
- 基于FPGA的电压表与串口通信(上)
实验原理 该实验主要为利用TLC549采集模拟信号,然后将模拟信号的数字量通过串口发送到PC上上位机进行显示,使用到的TLC549驱动模块在进阶实验已经使用到了,串口模块在基础实验也已经使用到了,本实 ...
- Matlab中给figure添加图例(legend),标题(title)和颜色(color)
在Matlab绘图过程中,尤其是需要将多个图绘制在相同的坐标轴中时,通常需要将不同的曲线设置成为不同的颜色.此外,为了直观,还需要给这张图标增添标题和图例.这篇文章展示了在Matlab的绘图窗口(fi ...
- 1027mysqlbinlog工具日志恢复
-- 转自http://bbs.csdn.net/topics/310068149-- 其实就是找到对应的位置然后执行语句即可 -- 第一部分 输出mysqlbinlog "C:\Progr ...