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 }

posted on 2012-04-12 09:27  Inpeace7  阅读(248)  评论(0编辑  收藏  举报

导航