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,黑人问号??? 这题可以用线段树 ...
随机推荐
- C#数组比较取值
string strs = string.Empty; string[] strArray1 = { "a", "b", "c& ...
- linux中sed用法
sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作,下面先了解一下sed的用法sed命令行格式为: sed ...
- 把CheckedListBoxControl设置为单选框
private void chkControl_ItemChecking(object sender, DevExpress.XtraEditors.Controls.ItemCheckingEven ...
- 设置win7任务栏显示标题,而不显示缩略图
win7系统的任务栏可以显示桌面缩略图,这是非常好的一个功能,但是有时候我们希望只显示标题,如下所示 怎样设置呢?只要在桌面上的计算机图标上面“右键”,选择“属性”,在弹出的窗口选择“高级系统设置”, ...
- CSS 元素垂直居中的 6种方法
利用CSS进行元素的水平居中,比较简单,行级元素设置其父元素的text-align center,块级元素设置其本身的left 和 right margins为auto即可.本文收集了六种利用css进 ...
- block的动态传值例子
/* 写一个block传值 ,让两个数进行相除和相乘,在运行时动态决定采用哪种计算方式 */ #import <Foundation/Foundation.h> int main(in ...
- Unity连接本地数据库sqlite
首先要创建一个sqlite的数据库,记住文件地址,拷贝到Assets目录下,创建的数据库文件后缀为.sqlite.具体创建方法百度sqlite 然后百度Mono.Data.Sqlite,这是一个dll ...
- JavaScript--面向对象与原型(15)
// ECMAScript有两种开发模式:1.函数式(过程化);2.面向对象(OOP); 一 创建对象 1.普通的创建对象 1 // 创建一个对象,然后给这个对象新的属性和方法; 2 var box ...
- 有道单词本添加js实现自动阅读单词
个人比较习惯使用有道,使用了一段时间,背单词的时候很不方便 而有道单词客户Duan没有自动阅读的功能, 本菜用强大的js实现了简单的自动下一个单词的功能, 方法:第一步打开有道路径下的" ...
- 3月31日学习笔记(CSS基础)
背景属性 文本属性 direction 属性影响块级元素中文本的书写方向.表中列布局的方向.内容水平填充其元素框的方向.以及两端对齐元素中最后一行的位置. 注释:对于行内元素,只有当 unicode- ...