zoukankan      html  css  js  c++  java
  • hdu3450

    分析:首先要知道有递推公式dp[i] = Sigma(dp[j]),dp[i]表示第i个数结尾的完美子序列的个数,|a[i] - a[j]| <= d,j<i。直接这样做的时间复杂度为n^2,对于最大有100000的n还是会超时的,留意到公式是连续加的(j<i 时,以[a[i] - d, a[i] + d]区间里面的数结尾的完美子序列个数相加),其实j>i的[a[i] - d, a[i] + d]区间里面的数结尾的完美子序列个数也可以加进去,只要初始化都为0,正因为这样可以用树状数组对这种加法进行加速,只要先用二分查找出区间两端点对应在树状数组里面的下标。

     1 #pragma warning(disable:4996)
     2 #include <cstdio>
     3 #include <set>
     4 #include <stack>
     5 #include <vector>
     6 #include <algorithm>
     7 #include <map>
     8 #define MOD 9901
     9 using namespace std;
    10 int bit[100005];//bit -- binary indexed tree
    11 int a[100005], order[100005], len;
    12 int lowBit(int x){
    13     return x & (-x);
    14 }
    15 //size是数组的大小,val是增量
    16 void update(int idx, int size, int val){
    17     while (idx <= size){
    18         bit[idx] += val;
    19         if (bit[idx] >= MOD){
    20             bit[idx] %= MOD;
    21         }
    22         idx += lowBit(idx);
    23     }
    24 }
    25 //求a[1]到a[idx]的连续子序列的和
    26 int sum(int idx){
    27     int ret = 0;
    28     while (idx > 0){
    29         ret += bit[idx];
    30         if (ret >= MOD){
    31             ret %= MOD;
    32         }
    33         idx -= lowBit(idx);
    34     }
    35     return ret;
    36 }
    37 int main(){
    38     int n, d, len;
    39     while (~scanf("%d%d", &n, &d)){
    40         for (int i = 1; i <= n; i++){
    41             scanf("%d", &a[i]);
    42         }
    43         copy(a + 1, a + 1 + n, order + 1);
    44         sort(order + 1, order + 1 + n);
    45         len = unique(order + 1, order + 1 + n) - order - 1;
    46         memset(bit, 0, sizeof(bit));
    47         for (int i = 1; i <= n; i++){
    48             int r = upper_bound(order + 1, order + 1 + len, a[i] + d) - order - 1;
    49             int l = lower_bound(order + 1, order + 1 + len, a[i] - d) - order - 1;
    50             int p = lower_bound(order + 1, order + 1 + len, a[i]) - order;
    51             int temp = sum(r) - sum(l);
    52             temp = (temp % MOD + MOD) % MOD;
    53             update(p, len, temp + 1);
    54         }
    55         printf("%d
    ", ((sum(len) - n) % MOD + MOD) % MOD);
    56     }
    57     return 0;
    58 }
  • 相关阅读:
    subString源码分析
    我的three.js学习记录(三)
    我的three.js学习记录(二)
    2017-10-15
    我的three.js学习记录(一)
    我的Spring学习记录(三)
    我的Spring学习记录(二)
    我的Hibernate学习记录(二)
    我的Hibernate学习记录(一)
    Tomcat学习笔记
  • 原文地址:https://www.cnblogs.com/ZShogg/p/3553816.html
Copyright © 2011-2022 走看看