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,黑人问号??? 这题可以用线段树 ...
随机推荐
- EntityFramework Core 封装
public class EntityBaseRepository<T> : IEntityBaseRepository<T> where T : class, IEntity ...
- IntelliJ IDEA 编译maven项目以及运行测试前编译项目
Maven编译及命令行输出 右侧Maven Projects, 打开, 选取某个Project打开至Lifecycle/package 或其他任何一个lifecycle选项, 在上面右键Run Mav ...
- IntelliJ IDEA 打包可运行的 JAR
## 构建说明 创建Artifest任务 * File -> Project Structure -> Artifacts -> + JAR* 选择 From module with ...
- 01传智_jbpm与OA项目_整体项目架构
oA项目: 项目结构如下:
- jQuery offset,position,offsetParent,scrollLeft,scrollTop html控件定位 css position
定位应用:点击一个按钮,然后在按钮的右边弹出一个提示框 1,提示框相对于屏幕进行定位,那么使用offset来取得当前按钮相对于body的top和left,然后通过$('body').prepend(t ...
- Shell脚本语法
索引 1. 第一行必须是"#!/bin/sh" 2. 注释:一行开头为 # 3. 定义变量 4. 逻辑符号 5. 接收参数 6. 控制流:if/then/elif/else/f ...
- Android项目,从web上取下汉字,中文部分乱码
Android项目,从web上取下汉字,中文部分乱码. 常见问题,搜索一下,网上有很多办法解决.如果还没有试过这个办法,可以尝试一下. BufferedReader in = new Buffered ...
- String PK StringBuilder,传说就是传说,只有动手实验,才能得出确定的答案
本机测试结果如下: 大部分情况下,string 性能并不比StringBuilder差,只有特殊情况才出现差异,并非 如前面有些朋友测试的结果哪样,只要使用StringBuilder 就一定比Stri ...
- js 随笔
setInterval:即使在方法中使用了stopInterval这个方法也要执行完才会停止自行重复执行,解决:使用return false来跳出方法. JS string和num:当一个是字符串数字 ...
- 完美演绎DevExpress XtraPrinting Library 的打印功能
完美演绎DevExpress XtraPrinting Library 的打印功能 2010-05-14 17:40:49| 分类: 默认分类|字号 订阅 设计报告不仅费时间,而且还乏味!但 ...