题意:
给了一个数列,长度为N(1<=N<=50000)..现在问从这个序列中取出5个子序列...并且是严格递增的.有多少个..
题解:
首先想到的是dp...dp[t][x]代表当前最后一个数位x,.长度为x的递增子序列有多少个..更新就是将比他前方小的所有dp[t-1][i]加起来...
再看到每个数是小于10^9...而数列最长只有50000..想到离散化...先读进来..排序..后面二分来查位置..
然后看是要找她前方的所有比它小的树的t-1之和..想到单点更新区间查询..线段树和数状数组都可以维护...由于长度为5..用5个树..
最后要注意答案是连long long都存不下的..用大数..自己裸敲了一个大数类..每位存10^7是因为只做加法..减少位数提高运算效率..
Program:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<stack>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<time.h>
#define ll long long
#define oo 1000000009
#define MAXN 50005
#define pi acos(-1.0)
#define esp 1e-30
#define MAXD 4
using namespace std;
struct BigInt
{
int s[MAXD+1];
void operator = (int b)
{
BigInt C;
memset(s,0,sizeof(s));
int w=0;
while (b)
{
s[++w]=b%10000000;
b/=10000000;
}
}
BigInt operator + (BigInt b) const
{
int i;
BigInt C;
C=0;
for (i=1;i<=MAXD;i++)
{
C.s[i]=C.s[i]+s[i]+b.s[i];
C.s[i+1]=C.s[i]/10000000,C.s[i]%=10000000;
}
return C;
}
BigInt operator - (BigInt b) const
{
int i;
BigInt C;
C=0;
for (i=1;i<=MAXD;i++)
{
C.s[i]=C.s[i]+s[i]-b.s[i];
while (C.s[i]<0) C.s[i+1]--,C.s[i]+=10000000;
}
return C;
}
void output()
{
int i;
for (i=MAXD;i>=1;i--)
if (s[i]) break;
printf("%d",s[i]),i--;
for (;i>=1;i--) printf("%07d",s[i]);
printf("\n");
}
};
BigInt sum[5][MAXN];
int N;
void update(int tp,BigInt x,int k)
{
tp--;
while (k<=N)
{
sum[tp][k]=sum[tp][k]+x;
k+=k&(-k);
}
}
BigInt query(int tp,int k)
{
BigInt ans;
ans=0,tp--;
while (k)
{
ans=ans+sum[tp][k];
k-=k&(-k);
}
return ans;
}
int Data[MAXN],H[MAXN];
int Bsearch(int x)
{
int l=0,r=N+1,mid;
while (r-l>1)
{
mid=l+r>>1;
if (Data[mid]>x) r=mid;
else l=mid;
}
return l;
}
int main()
{
int i,t,x;
BigInt ans,temp;
freopen("input.txt","r",stdin); freopen("output.txt","w",stdout);
while (~scanf("%d",&N))
{
memset(sum,0,sizeof(sum)),temp=1;
for (i=1;i<=N;i++) scanf("%d",&H[i]),Data[i]=H[i];
sort(Data+1,Data+1+N);
for (i=1;i<=N;i++)
{
x=Bsearch(H[i]);
update(1,temp,x);
for (t=2;t<=5;t++)
update(t,query(t-1,x-1),x);
}
ans=0;
for (i=5;i<=N;i++) ans=ans+(query(5,i)-query(5,i-1));
ans.output();
}
return 0;
}