zoukankan      html  css  js  c++  java
  • hdu-2227-dp+bit

    Find the nondecreasing subsequences

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2213    Accepted Submission(s): 858


    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
         
        令f(i)表示以第i个元素为结尾的非递减子序列的个数,有 f(i)=SUM{f(j) | j<i&&a[j]<=a[i]}。
            用BIT来维护f,C[x]表示所有的f总和,下标反映的就是a[i]得值,这样在求解f(i)=sum(a[i])就好了。
        注意到ai范围较大,离散化处理一下。
     
      
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define ULL unsigned long long 
     4 #define LL long long 
     5 LL mod=1e9+7;
     6 LL C[100010];
     7 int N;
     8 struct node{
     9     int v,d;
    10     bool operator<(const node& C)const{
    11         if(v!=C.v) return v<C.v;
    12         return d<C.d;
    13     }
    14 }a[101010];
    15 bool cmp(node A,node B){return A.d<B.d;}
    16 int main(){
    17     int i,j;
    18     while(scanf("%d",&N)==1){
    19         LL ans=0;
    20         for(i=1;i<=N;++i) scanf("%d",&a[i].v),a[i].d=i;
    21         sort(a+1,a+1+N);
    22         for(i=1;i<=N;++i) a[i].v=i;
    23         sort(a+1,a+1+N,cmp);
    24         for(i=1;i<=N;++i){
    25             LL tmp=1;
    26             for(int x=a[i].v;x>0;x-=(x&-x)) (tmp+=C[x])%=mod;
    27             for(int x=a[i].v;x<=N;x+=(x&-x)) (C[x]+=tmp)%=mod;
    28             (ans+=tmp)%=mod;
    29         }
    30         printf("%lld
    ",ans);
    31         memset(C,0,sizeof(C));
    32     }
    33     return 0;
    34 }
  • 相关阅读:
    关于lockkeyword
    关于多层for循环迭代的效率优化问题
    Android 面试精华题目总结
    Linux基础回想(1)——Linux系统概述
    linux源代码编译安装OpenCV
    校赛热身 Problem C. Sometimes Naive (状压dp)
    校赛热身 Problem C. Sometimes Naive (状压dp)
    校赛热身 Problem B. Matrix Fast Power
    校赛热身 Problem B. Matrix Fast Power
    集合的划分(递推)
  • 原文地址:https://www.cnblogs.com/zzqc/p/9371949.html
Copyright © 2011-2022 走看看