zoukankan      html  css  js  c++  java
  • 奶牛抗议 DP 树状数组

    奶牛抗议 DP 树状数组

    USACO的题太猛了

    容易想到(DP),设(f[i])表示为在第(i)位时方案数,转移方程:

    [f[i]=sum f[j];(j< i,sum[i]-sum[j]ge0) ]

    (O(n^2))过不了,考虑优化

    移项得:

    [f[i]=sum f[j];(j< i,sum[i]ge sum[j]) ]

    这时候我们发现相当于求在(i)前面并且前缀和小于(sum[i])的所有和,这就可以用一个树状数组优化了,在树状数组维护下标为(sum[i])(f[i])的前缀和。对于每个(f[i])即为树状数组上(sum[i])的前缀和。

    这里需要注意的是前缀和可能为负,而树状数组下标不能为负,所以我们要离散化一下。

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define MAXN 100010
    #define lowbit(x) ((x)&(-(x)))
    #define MOD 1000000009
    int n,sum[MAXN],s;
    int sum_sort[MAXN+1];
    int tre[MAXN+1];
    inline void add(int x, int val){
        while(x<=s){
            tre[x]=(tre[x]+val)%MOD;
            x+=lowbit(x);
        }
    }
    inline int get_sum(int x){
        int res=0;
        while(x>0){
            res=(res+tre[x])%MOD;
            x-=lowbit(x);
        }
        return res;
    }
    int main(){
        scanf("%d", &n);
        for(int i=1;i<=n;++i)
            scanf("%d", &sum[i]),sum[i]+=sum[i-1];
        for(int i=1;i<=n;++i) sum_sort[i]=sum[i];
        sort(sum_sort, sum_sort+1+n);
        s=unique(sum_sort, sum_sort+1+n)-sum_sort;
        for(int i=0;i<=n;++i) sum[i]=lower_bound(sum_sort, sum_sort+s, sum[i])-sum_sort+1;
        add(sum[0], 1); // f[0]=1 计数dp初始化
        int ans=0;
        for(int i=1;i<=n;++i){
            ans=get_sum(sum[i]); // 获得f[i]
            add(sum[i], ans); // 维护树状数组
        }
        printf("%d
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    Java数据类型转换
    github的入门使用
    移动端的头部标签和meta
    gulp&gulp-less
    前端工程筹建NodeJs+gulp+bower
    jQuery 遍历
    JavaScript for...in 语句
    console.log在线调试
    sessionStorage html5客户端本地存储之sessionStorage及storage事件
    一个页面从输入url到加载完成的过程都发生了什么,请详细说明
  • 原文地址:https://www.cnblogs.com/santiego/p/11844590.html
Copyright © 2011-2022 走看看