版权声明:蒟蒻Blog随意转载 https://blog.csdn.net/a1799342217/article/details/81666592
树状数组 DP
表示以 结尾的上升子序列个数。那么有
我们用一个树状数组维护数 的 的和,因为要去重,每次要减掉之前位置的 。最终答案还要减掉长度为1的个数。
代码:
#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 100005
#define F inline
using namespace std;
const int p=1e9+7;
int n,m,s,l[N],a[N],b[N],f[N],t[N<<1];
F char readc(){
static char buf[100000],*l=buf,*r=buf;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
return l==r?EOF:*l++;
}
F int _read(){
int x=0,f=1; char ch=readc();
while (!isdigit(ch)) { if (ch=='-') f=-1; ch=readc(); }
while (isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=readc();
return x*f;
}
F void nsrt(int x,int w){ for (;x<=n;x+=x&-x) (t[x]+=w)%=p; }
F int srch(int x){ for (s=0;x;x-=x&-x) (s+=t[x])%=p; return s; }
int main(){
n=_read(); for (int i=1;i<=n;i++) a[i]=b[i]=_read();
sort(b+1,b+n+1),b[0]=unique(b+1,b+n+1)-b-1;
for (int i=1;i<=n;i++){
a[i]=lower_bound(b+1,b+b[0]+1,a[i])-b,f[i]=srch(a[i]-1)+1;
nsrt(a[i],((f[i]-f[l[a[i]]])%p+p)%p),l[a[i]]=i;
}
return printf("%d\n",((srch(b[0])-b[0])%p+p)%p),0;
}