题意:
给了一个数列,长度为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; }