中文题
显然要弄个dp出来
数据这么大 先离散化一下
dp[i] 以i为结尾的子序列数目
所有的数目加起来就是答案
dp[i] = dp[1...i-1] 加起来
树状数组维护下 线段树莫名其妙超时
#include<stdio.h> #include<algorithm> #include<string.h> #include<math.h> #include<set> #include<string> #include<map> using namespace std; typedef long long LL; #define inf 1e9 #define MAXN 200010 #define mod 1000000007 struct node { int num,pos; }z[MAXN]; int tree[MAXN]; int now[MAXN]; bool cmp(node a,node b) { return a.num<b.num; } int main() { int n; while(scanf("%d",&n)!=EOF) { memset(tree,0,sizeof(tree)); for(int i=1;i<=n;i++) { scanf("%d",&z[i].num); // y[i]=z[i].num; z[i].pos=i; } sort(z+1,z+n+1,cmp); now[z[1].pos]=1; int cnt=1; // for(int i=1;i<=n;i++) // printf("%d ",z[i].pos); // printf(" "); for(int i=2;i<=n;i++) { if(z[i].num!=z[i-1].num) { now[z[i].pos]=++cnt; } else { now[z[i].pos]=cnt; } } // for(int i=1;i<=n;i++) // printf("%d ",now[i]); // // printf(" "); //printf("%d ",now[1]); for(int i=1;i<=n;i++) { int a=1,b; b=now[i]; //printf("%d ",b); for(int j=b-1;j;j -= (j & -j)) { a=(a+tree[j])%mod; } for(int j=b;j<=cnt;j += (j & -j)) { tree[j]=(tree[j]+a)%mod; } } //printf("1"); // printf("%d ",cnt); // for(int i=1;i<=cnt;i++) // printf("%d ",tree[i]); int ans=0; for(int i=cnt;i;i -= (i & -i)) { ans=(ans+tree[i])%mod; } printf("%d ",ans); } return 0; }