HDU 2227 Find the nondecreasing subsequences (线段树)
Find the nondecreasing subsequences
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1235 Accepted Submission(s): 431
Problem Description
How many nondecreasing subsequences can you find in the sequence S = {s1, s2, s3, ...., sn} ? For example, we assume that S = {1, 2, 3}, and you can find seven nondecreasing subsequences, {1}, {2}, {3}, {1, 2}, {1, 3}, {2, 3}, {1, 2, 3}.
Input
The input consists of multiple test cases. Each case begins with a line containing a positive integer n that is the length of the sequence S, the next line contains n integers {s1, s2, s3, ...., sn}, 1 <= n <= 100000, 0 <= si <= 2^31.
Output
For each test case, output one line containing the number of nondecreasing subsequences you can find from the sequence S, the answer should % 1000000007.
Sample Input
3
1 2 3
Sample Output
7
Author
8600
Recommend
lcy
解题思路: 每进来一个数,方法数是原来所有小于等于它的数的方法数之和+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; }