查找长度为5的上升序列总数
用的树状数组+高精度
用树状数组求在i前面比i小的数有几个
用的4个树状数组,A[i][j]表示长度为i的以j为结尾的个数,A[i][j]=A[i-1][1....flag[n]]
对数组下标不能为0一直不太理解,会发生死循环
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; #define N 50005 #define MOD 10000 struct e{ int w,id; bool operator <(const e &v) const { return w<v.w; } }a[N]; __int64 A[4][N]; int flag[N],ans[10],n; int lowbit(int x){ return x&-x; } void update(int x,int y,__int64 w) { while(y<n) { A[x][y]+=w; y+=lowbit(y); } } __int64 getsum(int x,int y) { __int64 sum=0; while(y>0) { sum+=A[x][y]; y-=lowbit(y); } return sum; } int ans_sum(__int64 w) //高精度取模 { int i; i=0; while(w>0) { ans[i]+=w%MOD; if(ans[i]>=MOD) { ans[i]-=MOD; ans[i+1]++; } w/=MOD; i++; } } int main() { int i,j; while(scanf("%d",&n)!=EOF) { // memset(arr,0,sizeof(arr)); for(i=1;i<=n;i++) { scanf("%d",&a[i].w); a[i].id=i; } sort(a,a+n); memset(ans,0,sizeof(ans)); memset(A,0,sizeof(A)); int mm=0; flag[a[1].id]=++mm; for(i=2;i<=n;i++) { if(a[i-1].w<a[i].w) flag[a[i].id]=++mm; else flag[a[i].id]=mm; } for(i=1;i<=n;i++) { __int64 x=1; for(j=0;j<4;j++) { update(j,flag[i],x); //x为长度为j-1的总数 x=getsum(j,flag[i]-1); } ans_sum(x); //对满足条件的进行求和 } int t=0; for(i=9;i>=0;i--) { if(!t&&ans[i]>0) { printf("%d",ans[i]); t=1; } else if(t) printf("%04d",ans[i]); } if(!t) printf("0"); printf("\n"); } return 0; }