标签:des style blog http ar io color os sp
3 1 2 3 2 2 1
1 3
这道题真心不会,看了题解和别人博客,问了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;
}
标签:des style blog http ar io color os sp
原文地址:http://blog.csdn.net/u013582254/article/details/41967361