http://acm.hdu.edu.cn/showproblem.php?pid=6348
开一个C数组。
当要找长度为x的答案时,
记录之前遍历x-1长度的a[i]的答案。
然后一个个加入树状数组更新即可。
因为随机:最长上升子序列的长度期望是 √n
所以可以暴力的来。期望效率是 √n*n*log(n)
#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
const int N = 1e4+2;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
int a[N],num[N];
int n;
void add(int x,int p)
{
for(int i=x;i<=n;i+=i&-i)
(num[i]+=p)%=mod;
}
int query(int x)
{
int ans=0;
for(int i=x;i>=1;i-=i&-i)
(ans+=num[i])%=mod;
return ans;
}
int ans[N];
int main()
{
int T,cas=0;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
num[i]=0;
ans[i]=0;
}
ans[1]=n;
int cnt=1;
int c[N];
for(int i=1;i<=n;i++)
c[i]=1;
while(ans[cnt]!=0&&cnt<=n){
cnt++;
for(int i=1;i<=n;i++)
num[i]=0;
for(int i=1;i<=n;i++){
add(a[i],c[a[i]]);
int b=query(a[i]-1);
(ans[cnt]+=b)%=mod;
c[a[i]]=b;
}
}
printf("Case #%d:",++cas);
for(int i=1;i<=n;i++)
printf(" %d",ans[i]);
printf("\n");
}
return 0;
}