https://www.bnuoj.com/v3/contest_show.php?cid=9149#problem/G

【题意】

给定一个数组a,问这个数组有多少个子序列,满足子序列中任意两个相邻数的差(绝对值)都不大于d.

【思路】

首先,朴素的dp思想:

dp[i]为以a[i]结尾的子问题的答案,则dp[i]=sum(dp[k]),k<i&&|a[k]-a[i]|<=d

但是时间复杂度为O(n^2),会超时。

我们可以这样想:

如果数组a排好序后,dp[i]就是区间(a[i]-d,a[i]+d)的结果和(直接把a[i]加到原数组后面)

所以自然而然就想到了用树状数组,区间求和求出dp[i],然后单点修改dp[i]以备后用。

这样时间复杂度就变成了O(nlogn)

另外要注意原来是很稀疏的大数据,我们要离散化压缩状态(排序去重)

先把长度为1的姑且认为是完美子序列,然后再减去n,怎样状态就很好转移,所以看到代码里fi初始值为1.

【Accepted】

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath> using namespace std;
const int mod=;
const int maxn=1e5+;
int n,d;
int a[maxn],h[maxn],tree[maxn];
int lowbit(int x)
{
return x&(-x);
}
void add(int k,int x)
{
while(k<=n)
{
tree[k]=(tree[k]+x)%mod;
k+=lowbit(k);
}
}
int query(int k)
{
int res=;
while(k)
{
res=(res+tree[k])%mod;
k-=lowbit(k);
}
return res;
}
int query(int l,int r)
{
return (query(r)-query(l-)+mod)%mod;
}
int main()
{
while(~scanf("%d%d",&n,&d))
{
memset(tree,,sizeof(tree));
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
h[i]=a[i];
}
sort(h+,h+n+);
int cnt=unique(h+,h+n+)-h-;
int ans=;
for(int i=;i<=n;i++)
{
int fi=;
int l=lower_bound(h+,h+cnt+,a[i]-d)-h;
int r=upper_bound(h+,h+cnt+,a[i]+d)-h-;
int pos=lower_bound(h+,h+cnt+,a[i])-h;
fi=(fi+query(l,r))%mod;
ans=(ans+fi)%mod;
add(pos,fi);
}
ans=(ans-n%mod+mod)%mod;
cout<<ans<<endl;
}
return ;
}

【知识点】

lower_bound返回第一个大于等于查找值的迭代器指针

upper_bound返回第一个大于(没有等于)查找值的迭代器指针

【(待重做)树状数组+dp+离散化】Counting Sequences的更多相关文章

  1. WUSTOJ 1337: Car race game(C)树状数组,离散化

    题目链接:1337: Car race game 参考资料:⑴ Car race game 树状数组 棋煜,⑵ 树状数组,⑶ 离散化 补充资料:⑴ qsort,⑵ 二分查找 Description B ...

  2. hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)

    Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java ...

  3. 【XSY2727】Remove Dilworth定理 堆 树状数组 DP

    题目描述 一个二维平面上有\(n\)个梯形,满足: 所有梯形的下底边在直线\(y=0\)上. 所有梯形的上底边在直线\(y=1\)上. 没有两个点的坐标相同. 你一次可以选择任意多个梯形,必须满足这些 ...

  4. 【POJ】3378 Crazy Thairs(树状数组+dp+高精)

    题目 传送门:QWQ 分析 题意:给个数列,求有多少五元上升组 考虑简化一下问题:如果题目求二元上升组怎么做. 仿照一下逆序对,用树状数组维护一下就ok了. 三元怎么做呢? 把二元的拓展一位就可以了, ...

  5. HDU 6447 YJJ’s Salesman (树状数组 + DP + 离散)

    题意: 二维平面上N个点,从(0,0)出发到(1e9,1e9),每次只能往右,上,右上三个方向移动, 该N个点只有从它的左下方格点可达,此时可获得收益.求该过程最大收益. 分析:我们很容易就可以想到用 ...

  6. hdu 4991(树状数组+DP)

    Ordered Subsequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  7. 【树状数组+dp】HDU 5542 The Battle of Chibi

    http://acm.hdu.edu.cn/showproblem.php?pid=5542 [题意] 给定长为n的序列,问有多少个长为m的严格上升子序列? [思路] dp[i][j]表示以a[i]结 ...

  8. The 2015 China Collegiate Programming Contest -ccpc-c题-The Battle of Chibi(hdu5542)(树状数组,离散化)

    当时比赛时超时了,那时没学过树状数组,也不知道啥叫离散化(貌似好像现在也不懂).百度百科--离散化,把无限空间中无限的个体映射到有限的空间中去,以此提高算法的时空效率. 这道题是dp题,离散化和树状数 ...

  9. HDU 3333 | Codeforces 703D 树状数组、离散化

    HDU 3333:http://acm.hdu.edu.cn/showproblem.php?pid=3333 这两个题是类似的,都是离线处理查询,对每次查询的区间的右端点进行排序.这里我们需要离散化 ...

随机推荐

  1. 利用autotools工具制作从源代码安装的软件 分类: linux 2014-06-02 23:27 340人阅读 评论(0) 收藏

    编写程序(helloworld.c)并将其放到一个单独目录. helloworld.c: #include<stdio.h> int main() { printf("hello ...

  2. http缓存之lastModified和etag

    1.cache-control 访问资源 首次访问页面时间:2018.2.1  9:56  (当前时间=GMT时间+8h) 缓存时长max-age:1 day Expire缓存失效时间:2018.2. ...

  3. L 裁纸片 贪心 + 模拟

    https://biancheng.love/contest-ng/index.html#/123/problems 如果只是输出最小的值,那么好办,a升序,b降序,这样是最优的. 但是需要次数,这就 ...

  4. web+ admin template,spa管理应用后台,easyui后台正式发布

    演示地址:http://admintemplate.webplus.org.cn/ v1.0 (2016/7/27) 扁平化风格 全屏支持 后台管理不使用iframe,全ajax开发 权限管理 商品管 ...

  5. 来自AJPFX的二分法查找

    package com.heima.array; public class Demo2_Array { /**         * * A:案例演示                        * ...

  6. Android学习笔记(七) 布局基础

    一.概念 控件布局方法,就是指控制控件在Activity当中的位置.大小.颜色以及其他控件样式属性的方法.有两种方法可以控制布局: 在布局文件(xxx.xml)中完成控件的布局. 在JAVA代码中完成 ...

  7. iOS---小经验分享

    1.字符串在block中得赋值 定义一个全局变量,<字符串>当这个字符串用copy修饰的时候,然后再在block中赋值,当在block块之外访问时,不能得到字符创的值.此时字符串应该设置为 ...

  8. PHP exif扩展方法开启详解(亲测)

    本节主要介绍了如何开启PHP exif扩展方法,主要在于对php.ini文件的修改 服务器配置说明: 1.在php.ini文件中找到;extension=php_exif.dll,去掉前面的分号 2. ...

  9. JAVA 学习笔记 - 反射机制

    1.   JAVA反射机制的概念 2. 怎样实例化一个 Class对象 Class.forName(包名.类名); 对象.getClass(); 类.class; ================== ...

  10. iTOP-4418/6818开发板支持双屏异显,双屏同显

    iTOP-4418/6818开发板平台安卓系统下支持双屏异显,双屏同显,客户可按照不同用途,分别播放适合屏幕显示方式的内容 ,如HDMI屏幕和LCD屏幕显示不同内容, 一个屏幕播放广告,另一个屏幕运行 ...