首页 > 代码库 > HDU 5141 LIS again
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 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 ).
S[ i , j ] indicates (
Your program, when given the numeric sequence (
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
Process to the end of file.
[Technical Specification]
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
这道题真心不会,看了题解和别人博客,问了bin巨,搞了半天才理解。
树状数组优化的是求解LIS和LIS最大的时候最靠右的位置。
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<iostream> #include<queue> #include<cmath> #include<map> #include<stack> #include<bitset> using namespace std; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define CLEAR( a , x ) memset ( a , x , sizeof a ) const int INF=0x3f3f3f3f; typedef long long LL; const int maxn = 100005; const int mod = 1000000007; int pos1[maxn],pos2[maxn],dp[maxn]; int a[maxn<<2],b[maxn<<2],sum[maxn][2],cnt,n;//sum[i][0]记录到i并且以i为结尾的最大的LIS的值,sum[i][0]记录LIS最大的条件下LIS最靠右的起始点的位置 int len,ans,pos; void work() { sort(b,b+cnt); cnt=unique(b,b+cnt)-b;//b数组的大小 REP(i,n) a[i]=lower_bound(b,b+cnt,a[i])-b+1; } int lowbit(int x) { return x&(-x); } void add(int x,int s,int p) { while(x<=cnt) { if(sum[x][0]<s) { sum[x][0]=s; sum[x][1]=p; } if(sum[x][0]==s&&sum[x][1]<p) sum[x][1]=p; x+=lowbit(x); } } void query(int x) { while(x) { if(ans<sum[x][0]) { pos=sum[x][1]; ans=sum[x][0]; } if(ans==sum[x][0]&&pos<sum[x][1]) pos=sum[x][1]; x-=lowbit(x); } } int main() { while(~scanf("%d",&n)) { cnt=0; REP(i,n) { scanf("%I64d",&a[i]); b[cnt++]=a[i]; } CLEAR(sum,0); work(); len=0; REP(i,n) { ans=0; query(a[i]-1); dp[i]=ans+1; if(ans==0) pos1[i]=i; else pos1[i]=pos; add(a[i],dp[i],pos1[i]); len=max(len,dp[i]); } int pre=n; for(int i=n-1;i>=0;i--) { if(dp[i]==len) { pos2[i]=pre-1; pre=i; } } LL s=0; for(int i=0;i<n;i++) { if(dp[i]==len) s+=(LL)(pos1[i]+1)*(pos2[i]+1-i); } printf("%I64d\n",s); } return 0; }
HDU 5141 LIS again
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。