HDOJ 5141 LIS again 二分

二分求LIS

对每一个位置为终点的LIS记录开头的最靠右边的值....

LIS again

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 272    Accepted Submission(s): 96

Problem Description

A numeric sequence of ai is ordered if a1<a2<…<aN.
Let the subsequence of the given numeric sequence (a1,a2,…,aN)
be any sequence (ai1,ai2,…,aiK),
where 1≤i1<i2<…<iK≤N.
For example, sequence (1, 7, 3, 5, 9, 4, 8) has ordered subsequences, eg. (1, 7), (3, 4, 8) and many others.

S[ i , j ] indicates ( ai,ai+1,ai+2,…,aj)
.

Your program, when given the numeric sequence (a1,a2,…,aN),
must find the number of pair ( i, j) which makes the length of the longest ordered subsequence of S[ i , j ] equals to the length of the longest ordered subsequence of (a1,a2,…,aN).

Input

Multi test cases (about 100), every case occupies two lines, the first line contain n, then second line contain n numbers a1,a2,…,aN separated
by exact one space.

Process to the end of file.

[Technical Specification]

1≤n≤100000

0≤ai≤1000000000

Output

For each case,.output the answer in a single line.

Sample Input

3
1 2 3
2
2 1

Sample Output

1
3

Source

BestCoder Round #21

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long int LL;
const int maxn=100100;

int a[maxn],c[maxn],w[maxn],p[maxn],l[maxn];
int len,n;
LL ans;

void init()
{
	ans=0; len=0;
	memset(w,-1,sizeof(w));
}

int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		init();
		for(int i=0;i<n;i++) scanf("%d",a+i);

		len=1; c[0]=a[0]; l[0]=1; p[0]=0; w[0]=0;

		for(int i=1;i<n;i++)
		{
			int j=lower_bound(c,c+len,a[i])-c;
			c[j]=a[i];

			if(j==0) w[j]=i;
			else w[j]=max(w[j],w[j-1]);

			p[i]=w[j];
			l[i]=j+1;

			if(j>=len) len++;
		}
		bool flag=false;
		int l1=-1;
		for(int i=0;i<n;i++)
		{
			if(l[i]==len)
			{
				flag=true;
				l1=max(l1,p[i]);
			}
			if(flag)
			{
				ans+=l1+1;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}
时间: 2024-10-29 04:09:39

HDOJ 5141 LIS again 二分的相关文章

POJ1836 Alignment 【LIS(二分)+枚举】

a1,a2,a3,a4,a5,a6...an 对ai求出a1到ai的lis,ai+1到an的lds 取所有ai对应的lis+lds最大值 输出n-lis-lds #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include <cstring> #include <cmath> using namespace std; int

SPOJ 3943 - Nested Dolls 最长不下降子序列LIS(二分写法)

现在n(<=20000)个俄罗斯套娃,每个都有宽度wi和高度hi(均小于10000),要求w1<w2并且h1<h2的时候才可以合并,问最少能剩几个. [LIS]乍一看跟[这题]类似,但是仔细看是有区别的,其实就相当于上一题多次求LIS,每次求完LIS后把得到的序列删去,然后重新求LIS,最后输出求LIS的次数,我一开始这样写,果然就TLE了.还是要另辟蹊径. 首先用贪心思想,先按照wi从大到小排序,wi相等的情况下hi从小到大,然后求最长不下降子序列(注意可以等于).输出其长度即可. 想

Hdoj 2333 Assemble 【二分】

Assemble Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 479    Accepted Submission(s): 169 Problem Description Recently your team noticed that the computer you use to practice for programming

HDU 5141 LIS again

Problem Description A numeric sequence of ai is ordered if a1<a2<-<aN. Let the subsequence of the given numeric sequence (a1,a2,-,aN) be any sequence (ai1,ai2,-,aiK), where 1≤i1<i2<-<iK≤N. For example, sequence (1, 7, 3, 5, 9, 4, 8) has

HDOJ 1257 LIS

题目大意: 输入N,表示雷达监测到来袭的导弹数目,之后输入每个导弹的发射高度,因为每套系统第一次发射的导弹高度任意高,后续发射的导弹不能高于先前的高度,所以计算打落所有导弹所需要的最小系统数量. 算法思想: 因为每套系统所发射的导弹是非递增的序列,所以只需求出所有来袭导弹的最长上升序列的规模数即为需要的系统数.用dp[i]记录到i的最长上升子序列,状态方程为 dp[i]=max(dp[j])+1 (1=<j<i) . 代码如下: #include <iostream> #inclu

hdoj 1969 Pie【二分】

Pie Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6320    Accepted Submission(s): 2383 Problem Description My birthday is coming up and traditionally I'm serving pie. Not just one pie, no, I h

UVa 10635 (LIS+二分) Prince and Princess

题目的本意是求LCS,但由于每个序列的元素各不相同,所以将A序列重新编号{1,2,,,p+1},将B序列重新编号,分别为B中的元素在A中对应出现的位置(没有的话就是0). 在样例中就是A = {1 7 5 4 8 3 9},B = {1 4 3 5 6 2 8 9} 重新编号以后: A = {1 2 3 4 5 6 7}, B = {1 4 6 3 0 0 5 7}(里面的0在求LIS时可以忽略) 这样求A.B的LCS就转变为求B的LIS 求LIS用二分优化,时间复杂度为O(nlogn) 第一次

LIS n*log(n)的理解

很多时候lis 用二分的方法比较方便 这里写一下他的原理 这里仅对严格的最长上升子序列做讨论 这里有两个数列  一个数列是 原串的数列 a1-an  另一个数列是最长上升子序列辅助数列 s数列的长度为 k, 是当前最长上升子序列长度 先来看看n*n的方法 dp[i]=max{dp[j]+1|j<i && ai>aj} s数列是  对于当前的串  a1-ak  最长上升子序列为k  j<=k 上升子序列长度为j的子串中,第j位最小的数为sj 用类似递推的思想 顺序从a1推到

【二分】【最长上升子序列】HDU 5489 Removed Interval (2015 ACM/ICPC Asia Regional Hefei Online)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5489 题目大意: 一个N(N<=100000)个数的序列,要从中去掉相邻的L个数(去掉整个区间),使得剩余的数最长上升子序列(LIS)最长. 题目思路: [二分][最长上升子序列] 首先,假设去掉[i,i+m-1]这L个数,剩余的LIS长度为max(i左端最后一个不大于a[i+m]的LIS长度+a[i+m]开始到最后的LIS长度). 所以,我们从n到1逆向先求最长下降子序列的长度f[i],就可以知