BZOJ 3173 [Tjoi2013] 最长上升子序列 解题报告
这个题感觉比较简单,但却比较容易想残。。
我不会用树状数组求这个原排列,于是我只好用线段树。。。毕竟 Gromah 果弱马。
我们可以直接依次求出原排列的元素,每次找到最小并且最靠右的那个元素,假设这是第 $i$ 次找的,那么这就是原排列的第 $i$ 项,然后我们就把这个元素删去(变成很大的数),再把这个数以左的数都加 1,进行下一轮。
然后就是裸的最长上升子序列啦~~~
时间复杂度 $O(n\log n)$,空间复杂度 $O(n)$。
#include <cstdio>
#include <algorithm>
using namespace std;
#define N 100000 + 5
#define M 262144 + 5
#define ls(x) x << 1
#define rs(x) x << 1 | 1 int n, Pos[N], A[N], T[N], F[N]; struct Segment_Tree
{
int Min, delta;
}h[M]; inline void Build(int x, int l, int r)
{
if (l == r)
{
h[x].Min = Pos[l];
return ;
}
int mid = l + r >> ;
Build(ls(x), l, mid);
Build(rs(x), mid + , r);
h[x].Min = min(h[ls(x)].Min, h[rs(x)].Min);
} inline void apply(int x, int d)
{
h[x].Min += d, h[x].delta += d;
} inline void push(int x)
{
if (h[x].delta)
{
apply(ls(x), h[x].delta);
apply(rs(x), h[x].delta);
h[x].delta = ;
}
} inline void Modify(int x, int l, int r, int s, int t, int d)
{
if (l == s && r == t)
{
apply(x, d);
return ;
}
push(x);
int mid = l + r >> ;
if (t <= mid) Modify(ls(x), l, mid, s, t, d);
else if (s > mid) Modify(rs(x), mid + , r, s, t, d);
else Modify(ls(x), l, mid, s, mid, d), Modify(rs(x), mid + , r, mid + , t, d);
h[x].Min = min(h[ls(x)].Min, h[rs(x)].Min);
} inline int Query(int x, int l, int r)
{
if (l == r) return l;
int mid = l + r >> ;
if (h[rs(x)].Min <= h[ls(x)].Min)
return Query(rs(x), mid + , r);
else return Query(ls(x), l, mid);
} int main()
{
#ifndef ONLINE_JUDGE
freopen("3173.in", "r", stdin);
freopen("3173.out", "w", stdout);
#endif scanf("%d", &n);
for (int i = ; i <= n; i ++)
scanf("%d", Pos + i);
Build(, , n);
for (int i = ; i <= n; i ++)
{
int t = Query(, , n);
Modify(, , n, , t, );
Modify(, , n, t, t, n);
if (!T[] || T[T[]] < t)
{
T[++ T[]] = t;
F[t] = T[];
}
else
{
int x = lower_bound(T + , T + T[] + , t) - T;
T[x] = t;
F[t] = x;
}
}
for (int i = , Max = ; i <= n; i ++)
{
Max = Max > F[i] ? Max : F[i];
printf("%d\n", Max);
} #ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
#endif
return ;
}
3173_Gromah
BZOJ 3173 [Tjoi2013] 最长上升子序列 解题报告的更多相关文章
- BZOJ 3173: [Tjoi2013]最长上升子序列
3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1524 Solved: 797[Submit][St ...
- 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]最长上升子序列 (线段树+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,黑人问号??? 这题可以用线段树 ...
随机推荐
- InternetOpen怎么使用代理
如果你用IE的默认代理设置:hinternet=InternetOpen(AfxGetAppName(),INTERNET_OPEN_TYPE_PROXY,NULL,NULL,0); 把INTERNE ...
- jquery学习--选择器
选择器:basic $('button') html 标签 $('#test') 标签ID $('.test') 标签的class $('.test,#test,h1') 多选用逗号隔开 $('*') ...
- html dom的加载
操作HTML DOM文档的一个难题是,你的JavaScript代码可能在DOM完全载入之前运行,这会导致你的代码产生一些问题.页面加载时浏览器内部操作的顺序大致是这样的: 1. HTML被解析. 2. ...
- 简单快速的伪Fractional Cascading
Fractional Cascading算法是用于将零散的多个数组(亦可理解成比较高维的空间)中的数据的二分查找速度增加,用的是空间换时间的方法.然而这种方法并不是很好懂,而且中文文献很少.在这里介绍 ...
- (转)MongoDb的十个使用要点
从 mongodb 阶段性技术总结 中抽取并整理了对大家有帮助的十个要点: 1.mongodb 表名和字段名统一用小写字母 mongodb 是默认区分大小写的,为了避免以前在 mysql 下遇到的 ...
- css 笔记——设置禁用中文输入法
ime-mode ime-mode的语法解释如下: ime-mode : auto | active | inactive | disabled 取值: auto : 默认值.不影响IME的状态.与 ...
- spring集合类型的setter注入的一个简单例子
在项目中我们有时候会为集合类型设定一些默认的值,使用spring后,我们可以通过配置文件的配置,用setter方式为对象的集合属性提供一些默认值,下面就是一个简单的例子. 首先我们创建了一个名为Col ...
- Contest1065 - 第四届“图灵杯”NEUQ-ACM程序设计竞赛(个人赛)E粉丝与分割平面
题目描述 在一个平面上使用一条直线最多可以将一个平面分割成两个平面,而使用两条直线最多可将平面分割成四份,使用三条直线可将平面分割成七份--这是个经典的平面分割问题,但是too simple,作为一个 ...
- 【Winform】 Enum逆向解析
将字符串转换成Enum类型 Enum.Parse:将一个或多个枚举常数的名称或数字值的字符串表示转换成等效的枚举对象. 名称 说明 Parse(Type, String) 将一个或多个枚举常数 ...
- 数据库降级-从sqlserver 2008 降到 2005
前天遇到一个问题,是一个数据库是Sqlserver 2008的,而平台数据库库是2005的,需要把2008的数据库附加进来,试了很多办法,现在觉得最好的办法就是导出导入办法. 第一步 新建一个Sqls ...