zoukankan      html  css  js  c++  java
  • CodeForces 314C 树状数组 + dp

    //CodeForces 314C
    //分析:相当于求给定序列的不降子序列的个数,从一个空序列开始将得到的不降子序列不断的延长是典型的做法,则dp[i]表示以第 i 个元素结尾的序列
    //思路:O(n^2) 的做法,dp[i] = sum(dp[j]]) (a[j] <= a[i] && j <= i),求和过程用掉了 O(n) 的复杂度,用树状数组可以优化成 O(logn),需要先处理出每个元素在原来的序列中的大小顺序,最终复杂度 O(nlogn)。

     1 #include "iostream"
     2 #include "cstdio"
     3 #include "cstring"
     4 #include "algorithm"
     5 using namespace std;
     6 int n;
     7 struct st
     8 {
     9     int ans, rank, pos;
    10 } a[100010];
    11 int tot;
    12 bool cmp_1(st a, st b)
    13 {
    14     return a.ans < b.ans;
    15 }
    16 bool cmp_2(st a, st b)
    17 {
    18     return a.pos < b.pos;
    19 }
    20 
    21 inline int lowbit(int p)
    22 {
    23     return p&-p;
    24 }
    25 const int mod = 1000000007;
    26 
    27 const int maxn = 100010;
    28 int t[maxn], element[maxn];
    29 void add(int p, int x)
    30 {
    31     int i;
    32     for(i = p; i <= tot; i += lowbit(i)) {
    33         t[i] += x;
    34         t[i] %= mod;
    35     }
    36 }
    37 
    38 __int64 sum(int p)
    39 {
    40     int i, res = 0;
    41     for(i = p; i >= 1; i -= lowbit(i)) {
    42         res += t[i];
    43         res %= mod;
    44     }
    45     return res;
    46 }
    47 
    48 int main()
    49 {
    50     int i, j;
    51     scanf("%d", &n);
    52     for(i = 1; i<=n; ++i) {
    53         scanf("%d", &a[i].ans);
    54         a[i].pos = i;
    55     }
    56     sort(a+1, a+1+n, cmp_1);
    57     tot = 1;
    58     a[1].rank = 1;
    59     for(i = 2; i<=n; ++i) {
    60         if(a[i].ans!=a[i-1].ans)
    61             a[i].rank = ++tot;
    62         else
    63             a[i].rank = tot;
    64     }
    65     sort(a+1, a+1+n, cmp_2);
    66     int tmp;
    67     for(i = 1; i<=n; ++i) {
    68         tmp = (sum(a[i].rank)*a[i].ans%mod+a[i].ans)%mod;   //a[i].ans 是对空串的延长,因为 树状数组 不能计算到 t[0],不然就不用特殊处理空串的情况了
    69         add(a[i].rank, (tmp-element[a[i].rank]+mod)%mod);   //减去重复计算值,即上一次的计算值
    70         element[a[i].rank] = tmp;   //记录上一次的计算值
    71     }
    72     printf("%d
    ", sum(tot));
    73 }
  • 相关阅读:
    大内密探HMM(转)
    广义线性模型(logistic和softmax)
    百度首席科学家 Andrew Ng谈深度学习的挑战和未来(转载)
    推荐系统中的SVD
    Leveldb源码解析之Bloom Filter
    redis源码解析之事件驱动
    I/O多路复用机制:epoll
    redis源码解析之内存管理
    Redis源码解析之ziplist
    redis源码解析之dict数据结构
  • 原文地址:https://www.cnblogs.com/AC-Phoenix/p/4286618.html
Copyright © 2011-2022 走看看