HDU3564:Another LIS(线段树单点+LIS)
来源:互联网 发布:pl sql 日期格式 编辑:程序博客网 时间:2024/05/10 21:39
Problem Description
There is a sequence firstly empty. We begin to add number from 1 to N to the sequence, and every time we just add a single number to the sequence at a specific position. Now, we want to know length of the LIS (Longest Increasing Subsequence) after every time's add.
Input
An integer T (T <= 10), indicating there are T test cases.
For every test case, an integer N (1 <= N <= 100000) comes first, then there are N numbers, the k-th number Xk means that we add number k at position Xk (0 <= Xk <= k-1).See hint for more details.
For every test case, an integer N (1 <= N <= 100000) comes first, then there are N numbers, the k-th number Xk means that we add number k at position Xk (0 <= Xk <= k-1).See hint for more details.
Output
For the k-th test case, first output "Case #k:" in a separate line, then followed N lines indicating the answer. Output a blank line after every test case.
Sample Input
130 0 2
Sample Output
Case #1:112HintIn the sample, we add three numbers to the sequence, and form three sequences.a. 1b. 2 1c. 2 1 3
题意:给出1~n的插入顺序,要求每次插入之后的LIS
这道题还真是花费了不少时间,理解别人代码也花了很久时间,一直在纠结着如何去算LIS,前面还是很简单的,裸的线段树数空格问题,后面LIS的求法看别人的代码确实挺妙,这是用的将每个数的位置存起来,因为数值只有1~n,在这里确实很适合,只要记录了位置,再一次LIS即可。这个思想很巧妙,减一大家自己在演草纸上模拟下,大概思想就是,按照1~n循环下去,这个序列必定是递增的,再比较位置,因为数值递增,所以在保证LIS足够长的情况下,位置小的取小者,最后可以得到最长的值
#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;int n,s[1000000],dp[1000000],ans[1000000],len;//ans[i]代表i在位置ans[i];struct node{ int l,r,n;} a[1000000];void init(int l,int r,int i){ a[i].l = l; a[i].r = r; if(l == r) { a[i].n = 1; return ; } int mid = (l+r)>>1; init(l,mid,i*2); init(mid+1,r,i*2+1); a[i].n = a[i*2].n+a[i*2+1].n;}void insert(int i,int x,int m){ if(a[i].l == a[i].r) { ans[m] = a[i].l; a[i].n=0; return; } a[i].n--; if(x<=a[2*i].n) insert(2*i,x,m); else insert(2*i+1,x-a[2*i].n,m);}int bin(int k){ int l = 1,r = len; while(l<=r) { int mid = (l+r)>>1; if(k>dp[mid]) l = mid+1; else r = mid-1; } return l;}int main(){ int t,i,j,cas = 1; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i = 1; i<=n; i++) { scanf("%d",&s[i]); dp[i] = 0; } init(1,n,1); printf("Case #%d:\n",cas++); for(i = n; i>0; i--)//典型的数空位线段树 insert(1,s[i]+1,i); len = 0; for(i = 1; i<=n; i++)//LIS() { int k = bin(ans[i]); len = max(len,k); dp[k] = ans[i]; printf("%d\n",len); } printf("\n"); } return 0;}
- HDU3564:Another LIS(线段树单点+LIS)
- HDU3564 Another LIS 线段树
- 【线段树】【LIS】Another Lis HDU3564 UESTC2010
- hdu3564 Another LIS (线段树处理后的裸LIS)
- HDU3564——Another LIS(线段树)
- Another Lis HDU3564 UESTC2010
- hdu3564 Another LIS
- HDOJ 题目3564 Another LIS(线段树单点更新,LIS)
- hdu 3564 Another LIS(线段树+lis)
- hdu_3564_Another LIS(线段树+LIS)
- HDU 3564 Another LIS 线段树+最长上升子序列
- HDU3564Another LIS(线段树,LIS升级)
- hdu 3564 线段树+LIS
- HDU 3564 线段树+LIS
- HDU_5141 LIS again[线段树]
- hdu 3564(线段树+LIS)
- hdu 3564 Another Lis
- hdu3564(二分+线段树)
- 网游服务端开发入门知识
- 插画练习第一发
- Objective-C中用到一部分c语言没有的数据类型
- java collection framework 的一些比较使用的记录
- 虚基类的例子
- HDU3564:Another LIS(线段树单点+LIS)
- Matlab基本函数-disp函数
- 欢必有大才
- Android应用签名打包
- 含有纯虚函数的例子
- fork后的exec
- STL排序链表
- 读《effective java》笔记一:遇到多个构造器参数时要考虑用构造器
- linux内核移植-移植2.6.35.4内核到s3c2440