题意: 给定n,以及n个数(一个序列), 求在该序列中, 满足严格递增的子序列共有几个, 例如(1,3,2)中满足条件的子序列有(1), (1,3), (3), (1,2),(2)共5个;
解法:
从第一个数到第n个数,对于每个数来说, 若以该数(设该数为第i个数)为严格递增子序列的最后一个数,那么能得到的满足条件的子序列的数目ans[i] = sum(ans[j]) (1<=j<i && num[j] < num[i])
采用树状数组进行统计sum(ans[j])
由于所给数字过大,所以应当进行离散化
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 1e5+50;
const int mod = 1e9+7;
int num[maxn];
int p[maxn];
int c[maxn];
int lowbit(int x){
return x&(-x);
}
void update(int pos, int val, int n){
while(pos<=n){
c[pos]= (c[pos]+val)%mod;
pos += lowbit(pos);
}
}
int query(int pos){
int sum=0;
while(pos>0){
sum = (c[pos]+sum)%mod;
pos -= lowbit(pos);
}
return sum ;
}
bool cmp(int a, int b){
return a<b;
}
int findID(int x, int n){
int pos = lower_bound(p, p+1+n, x) - p;
return pos;
}
bool flag[maxn];
int main(){
int n,i;
while(~scanf("%d", &n)){
memset(c, 0, sizeof(c));
memset(flag, 0, sizeof(flag));
memset(p, inf, sizeof(p));
p[0]=0;
for(i=1; i<=n; i++){
scanf("%d", &num[i]);
p[i] = num[i];
}
sort(p+1, p+n+1, cmp);
for(i=1; i<=n; i++){
int q = findID(num[i], n);
int t=q-1;
while(flag[q]) q++;
update(q,(query(t)+1)%mod,n);
flag[q]=1;
}
int ans = query(n)%mod;
printf("%d\n", ans);
}
}