码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5141 LIS again

时间:2014-12-16 22:40:59      阅读:304      评论:0      收藏:0      [点我收藏+]

标签:des   style   blog   http   ar   io   color   os   sp   

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 1i1<i2<<iKN. 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]
1n100000
0ai1000000000
 

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


这道题真心不会,看了题解和别人博客,问了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

标签:des   style   blog   http   ar   io   color   os   sp   

原文地址:http://blog.csdn.net/u013582254/article/details/41967361

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!