lightoj 1085 All Possible Increasing Subsequences

来源:互联网 发布:网络用语103是啥意思 编辑:程序博客网 时间:2024/06/01 09:39

树状数组+dp


用树状数组来求和

dp时用dp[i]表示以a[i]为序列最好一个数字的上升序列的个数 其值等于前面所有dp[1-(i-1)]且(a[i-1]小于a[i]的值)的和

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define i64 long longconst int maxNode = 100010;int a[maxNode],p[maxNode],num;i64 ans,dp[maxNode],C[maxNode];const i64 mod = 1000000007;int lowbit(int x){    return x&(-x);}int search(int s,int e,int m){    while(s<=e)    {int mid = (s+e)>>1;if(p[mid]==m)    return mid;if(p[mid]>m){      e = mid-1;}else    s = mid+1;    }    return -1;}int sum(int pos){    int s = 0;    while(pos>0)    {s = (s+C[pos])%mod;pos -= lowbit(pos);    }    return s;}void add(int pos,int val,int m){    while(pos<=m)    {C[pos] = (C[pos]+val)%mod;pos += lowbit(pos);    }}int main(){    int t,m;    scanf("%d",&t);    for(int k = 1;k<=t;k++)    {memset(dp,0,sizeof(dp));memset(C,0,sizeof(C));int n;scanf("%d",&n);for(int i = 1;i<=n;i++){    scanf("%d",&a[i]);    p[i] = a[i];}sort(p+1,p+n+1);for(int i = 2,m=1;i<=n;i++){    if(p[i]!=p[i-1])    {p[++m] = p[i];num = m;    }}dp[1] = 1;ans = 1;add(search(1,num,a[1]),dp[1],num);for(int i = 2;i<=n;i++){    int pos = search(1,num,a[i]);    dp[i] = (sum(pos-1)+1)%mod;    ans = (ans+dp[i])%mod;    add(pos,dp[i],num);}printf("Case %d: %lld\n",k,ans);    }    return 0;}

FAQ | About Virtual Judge | Forum | Discuss | Open Source Project
All Copyright Reserved ©2010-2012 HUST ACM/ICPC TEAM
Anything about the OJ, please ask in the forum, or contact author:Isun
Server Time: 2013-06-22 15:56:47