3173: [Tjoi2013]最长上升子序列

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 1524  Solved: 797
[Submit][Status][Discuss]

Description

给定一个序列,初始为空。现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置。每插入一个数字,我们都想知道此时最长上升子序列长度是多少?

Input

第一行一个整数N,表示我们要将1到N插入序列中,接下是N个数字,第k个数字Xk,表示我们将k插入到位置Xk(0<=Xk<=k-1,1<=k<=N)

Output

N行,第i行表示i插入Xi位置后序列的最长上升子序列的长度是多少。

Sample Input

3
0 0 2

Sample Output

1
1
2

HINT

100%的数据 n<=100000

Source

[Submit][Status][Discuss]

分析

本来是想找Treap的练手题,考完NOIP放松一下心情的,结果看完题发现根本不用Treap……

首先,因为加入的元素是越来越大的,所以每次加入之后对于后面的元素的LIS的DP值(即以其结尾的最长上升子序列长度)不会改变,而前面的更不会改变。也就是说,最终序列的DP数组就是逐步加入的DP值了。所以只需要想方设法求出最终序列,再做一遍O(NlogN)的LIS问题即可。

求解最终的序列方法多种多样,可以用Treap暴力维护插入操作,也可以逆着推出最终的序列,我选择了后者。

对于第N个插入的元素,其插入的位置就是最终的位置。当它找到了最终位置之后,就把那个位置改为空。类似的,每个元素的最终位置,就是此时的第Xk个非空位置。这个操作用线段树维护即可轻松做到O(logN),当然也可以树状数组+二分做到O(log^2N),常数小也许跑得反而更快,(lll¬ω¬)。

代码

  1 #include <bits/stdc++.h>
  2
  3 using namespace std;
  4
  5 #define low lower_bound
  6 #define upp upper_bound
  7
  8 const int N = 100005;
  9 const int inf = 0x3f3f3f3f;
 10
 11 int n;
 12 int pos[N];
 13 int num[N];
 14 int ans[N];
 15 int stk[N];
 16
 17 struct node
 18 {
 19     int lt, rt, sum;
 20
 21     node (void) :
 22         lt (0), rt (0), sum (0) {};
 23 };
 24
 25 node tree[N << 2];
 26
 27 void build (int p, int l, int r)
 28 {
 29     node &t = tree[p];
 30
 31     t.lt = l;
 32     t.rt = r;
 33
 34     t.sum = r - l + 1;
 35
 36     if (l != r)
 37     {
 38         int mid = (l + r) >> 1;
 39
 40         build (p << 1, l, mid);
 41         build (p << 1 | 1, mid + 1, r);
 42     }
 43 }
 44
 45 void change (int p, int pos, int val)
 46 {
 47     node &t = tree[p];
 48
 49     if (t.lt != t.rt)
 50     {
 51         int mid = (t.lt + t.rt) >> 1;
 52
 53         if (pos <= mid)
 54             change (p << 1, pos, val);
 55         else
 56             change (p << 1 | 1, pos, val);
 57
 58         t.sum = tree[p << 1].sum + tree[p << 1 | 1].sum;
 59     }
 60     else
 61         t.sum = val;
 62 }
 63
 64 int query (int p, int val)
 65 {
 66     node &t = tree[p];
 67
 68     if (t.lt != t.rt)
 69     {
 70         int tmp = tree[p << 1].sum;
 71
 72         if (val <= tmp)
 73             return query (p << 1, val);
 74         else
 75             return query (p << 1 | 1, val - tmp);
 76     }
 77     else
 78         return t.lt;
 79 }
 80
 81 signed main (void)
 82 {
 83     scanf ("%d", &n);
 84
 85     for (int i = 1; i <= n; ++i)
 86         scanf ("%d", pos + i);
 87
 88     build (1, 1, n);
 89
 90     for (int i = n; i >= 1; --i)
 91     {
 92         int t = query (1, pos[i] + 1);
 93         num[t] = i, change (1, t, 0);
 94     }
 95
 96     memset (stk, inf, sizeof(stk));
 97
 98     for (int i = 1; i <= n; ++i)
 99     {
100         *low (stk, stk + i, num[i]) = num[i];
101         ans[num[i]] = low (stk, stk + i, num[i]) - stk;
102     }
103
104     for (int i = 1; i <= n; ++i)
105         ans[i] = max (ans[i], ans[i - 1]);
106
107     for (int i = 1; i <= n; ++i)
108         printf ("%d\n", ans[i] + 1);
109 }

BZOJ_3173.cpp

后记:

大概是刚考完NOIP,又要准备学考,大家的刷题兴致不高啊,居然被我轻松拿了Day榜,(*^_^*)/。

No. User Nick Name AC Submit Ratio
1 YOUSIKI ねえ、あなたは知っていますか、桜の行方の速度は秒速5センチメートル 5 6 83.333%

@Author: YouSiki

转载于:https://www.cnblogs.com/yousiki/p/6087448.html

BZOJ 3173: [Tjoi2013]最长上升子序列相关推荐

  1. [BZOJ]3173: [Tjoi2013]最长上升子序列

    题解:   考虑按照元素升序加入  所以对位置在其后的元素LIS无影响 然后从前面位置的最大值转移过来就行 ,,,,平衡树无脑模拟 #include <algorithm> #includ ...

  2. bzoj 3173: [Tjoi2013]最长上升子序列(离线二分+树状数组)

    3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 2051  Solved: 1041 [Submit] ...

  3. 【BZOJ】3173: [Tjoi2013]最长上升子序列(树状数组)

    [题意]给定ai,将1~n从小到大插入到第ai个数字之后,求每次插入后的LIS长度. [算法]树状数组||平衡树 [题解] 这是树状数组的一个用法:O(n log n)寻找前缀和为k的最小位置.(当数 ...

  4. BZOJ3173 [TJOI2013]最长上升子序列

    题面: 3173: [Tjoi2013]最长上升子序列 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 2108  Solved: 1067 [Sub ...

  5. [TJOI2013]最长上升子序列

    [TJOI2013]最长上升子序列 题目大意: 给定一个序列,初始为空.将\(1\sim n(n\le10^5)\)的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字后输出LIS长 ...

  6. P4309 [TJOI2013]最长上升子序列 平衡树 + dp

    传送门 文章目录 题意: 思路: 题意: 思路: 注意到一个很关键的条件,每次插入iii,而iii是递增的,也就是说插入iii之后只会从前面的最大值转移过来,所以我们现在只需要维护插入操作即可,这个显 ...

  7. [BZOJ3173][Tjoi2013]最长上升子序列

    [BZOJ3173][Tjoi2013]最长上升子序列 试题描述 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上 ...

  8. 【bzoj 3173】[Tjoi2013]最长上升子序列

    Description 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? Input 第一行一 ...

  9. BZOJ3173:[TJOI2013]最长上升子序列(Splay)

    Description 给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? Input 第一行一 ...

最新文章

  1. 深度学习vs机器学习 | 这些本质区别你知道多少?
  2. SpringBoot返回枚举对象中的指定属性
  3. 独家 | 准确度VS速度——数据科学家能从搜索中学到什么?(附链接)
  4. 长得类似铁甲小宝的机器人_铁甲小宝:小时候只顾看机器人忽略重点,长大后再看:是我太天真...
  5. 程序员30岁后,9分钟跑完1600米
  6. iOS Apps核心对象
  7. 注意!!Redis使用不当真的可能会导致应用卡死
  8. aws php 上传文件 限制大小_如何压缩PDF文件大小,满足各种上传大小要求
  9. java appt,(转从ajava)打开ppt
  10. CentOS6.5下安装mongodb
  11. pyecharts显示所有x轴_基于Pyecharts可视化大屏案例一(1)
  12. 自然语言处理中的词性标注全称
  13. 捡到iphone6怎么解锁_赛博朋克2077前期手枪用哪个好?2077节制结局及银杯节制解锁条件...
  14. Unity3D 渲染管线全流程解析
  15. svn将本地项目传到svn
  16. 干货!量子技术入门、进阶、行业专家观点、最新资讯!1000篇好文帮你揭开量子技术神秘面纱!
  17. html调用wmp,web页面中嵌入window media player,支持IE和Chrome
  18. 5118站长工具箱:SEO数据分析浏览器插件 - 叶涛的博客
  19. PX90---Lags Backs
  20. ct上的img表示什么_X线/CT/MR影像片子上的标识你是否都认识?

热门文章

  1. 如何在国内下载Eclipse及其插件
  2. Linux shell 进制转换
  3. 快手文档 - www.kuaishou.net
  4. SQL2005 BI系列课程
  5. Video4Linux
  6. 【鬼网络】之PXE高效批量网络装机
  7. python三大流程控制
  8. 因子和(类素数筛选法)
  9. java null 转空_java 对象属性为 null 值转为 空串
  10. Linux系统TCP内核参数优化总结