poj 2227 dp+树状数组
给一个数组,求非递减数列的个数,单个数也算一个
dp[a[i]]=sum(dp[a[j]]) j<i && a[j]<a[i],意为最后一个数a[i]的非递减数列
若用线性方法,每一个a[i],都要去前边找比a[i]小的数,求和。O(N*N)超时
用树状数组求解,注意要离散化
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 6 using namespace std; 7 typedef long long ll; 8 #define lowbit(x) (x&(-x)) 9 const int maxx=150000; 10 int n; 11 struct NODE 12 { 13 ll data; 14 int in; 15 }node[maxx+10]; 16 17 ll tree[maxx+10]; 18 int p[maxx+10]; 19 20 bool cmp(NODE a,NODE b) 21 { 22 if(a.data!=b.data)return a.data<b.data; 23 else return a.in<b.in; 24 } 25 26 void update(int i,ll val) 27 { 28 while(i<=n) 29 { 30 tree[i]+=val; 31 i+=lowbit(i); 32 if(tree[i]>=1000000007) 33 tree[i]%=1000000007; 34 } 35 } 36 ll getsum(int i) 37 { 38 ll sum=0; 39 while(i>0) 40 { 41 sum+=tree[i]; 42 i-=lowbit(i); 43 if(sum>=1000000007) 44 sum%=1000000007; 45 } 46 return sum; 47 } 48 49 int main() 50 { 51 int i,cnt; 52 ll ans,temp; 53 freopen("in.txt","r",stdin); 54 while(scanf("%d",&n)!=EOF) 55 { 56 ans=0; 57 memset(tree,0,sizeof(tree)); 58 memset(p,0,sizeof(p)); 59 for(i=1;i<=n;i++) 60 { 61 scanf("%lld",&node[i].data); 62 node[i].in=i; 63 } 64 sort(node+1,node+n+1,cmp); 65 cnt=1; 66 p[node[1].in]=1; 67 for(i=2;i<=n;i++) 68 { 69 if(node[i].data==node[i-1].data)p[node[i].in]=cnt; 70 else p[node[i].in]=++cnt; 71 } 72 update(p[1],1); 73 ans=1; 74 for(i=2;i<=n;i++) 75 { 76 temp=getsum(p[i]); 77 update(p[i],temp+1); 78 ans+=(temp+1); 79 if(ans>=1000000007) 80 ans%=1000000007; 81 82 } 83 printf("%lld\n",ans); 84 } 85 return 0; 86 }