Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1235 Accepted Submission(s): 431
解题思路: 每进来一个数,方法数是原来所有小于等于它的数的方法数之和+1,然后再把这个数添加进为原来的数,下面依次循环。
100000个数,但是数值比较大,所以离散化一下,线段树来维护,每次lg的操作
因此总效率 O(n^lgn)
#include <iostream> #include <cstdio> #include <map> #include <algorithm> using namespace std; const int maxn=100010; const int yu= 1000000007; int n; unsigned int data[maxn]; map <unsigned int,int> mp; struct node{ int l,r; unsigned c; }a[maxn*4]; void build(int l,int r,int k){ a[k].l=l;a[k].r=r;a[k].c=0; if(l<r){ int mid=(l+r)/2; build(l,mid,2*k); build(mid+1,r,2*k+1); } } void insert(int l,int r,int c,int k){ a[k].c=(a[k].c+c)%yu; if(l<=a[k].l && a[k].r<=r) return; else{ int mid=(a[k].l+a[k].r)/2; if(l>=mid+1) insert(l,r,c,2*k+1); else if(r<=mid) insert(l,r,c,2*k); else{ insert(l,mid,c,2*k); insert(mid+1,r,c,2*k+1); } } } unsigned query(int l,int r,int k){ if(l<=a[k].l && a[k].r<=r){ return a[k].c; }else{ int mid=(a[k].l+a[k].r)/2; if(l>=mid+1) return query(l,r,2*k+1); else if(r<=mid) return query(l,r,2*k); else{ return (query(l,mid,2*k)+query(mid+1,r,2*k+1))%yu; } } } void initial(){ mp.clear(); build(1,n,1); } void input(){ int cnt=1; map <unsigned int,int>::iterator it; for(int i=1;i<=n;i++){ scanf("%d",&data[i]); mp[data[i]]=0; } for(it=mp.begin();it!=mp.end();it++){ it->second=cnt++; } } void computing(){ int ans=0,tmp,pos; for(int i=1;i<=n;i++){ pos=mp[data[i]]; tmp=query(1,pos,1)+1; ans=(ans+tmp)%yu; insert(pos,pos,tmp,1); } cout<<ans<<endl; } int main(){ while(scanf("%d",&n)!=EOF){ initial(); input(); computing(); } return 0; }