【(待重做)树状数组+dp+离散化】Counting Sequences
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的更多相关文章
- WUSTOJ 1337: Car race game(C)树状数组,离散化
题目链接:1337: Car race game 参考资料:⑴ Car race game 树状数组 棋煜,⑵ 树状数组,⑶ 离散化 补充资料:⑴ qsort,⑵ 二分查找 Description B ...
- hdu 3030 Increasing Speed Limits (离散化+树状数组+DP思想)
Increasing Speed Limits Time Limit: 2000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- 【XSY2727】Remove Dilworth定理 堆 树状数组 DP
题目描述 一个二维平面上有\(n\)个梯形,满足: 所有梯形的下底边在直线\(y=0\)上. 所有梯形的上底边在直线\(y=1\)上. 没有两个点的坐标相同. 你一次可以选择任意多个梯形,必须满足这些 ...
- 【POJ】3378 Crazy Thairs(树状数组+dp+高精)
题目 传送门:QWQ 分析 题意:给个数列,求有多少五元上升组 考虑简化一下问题:如果题目求二元上升组怎么做. 仿照一下逆序对,用树状数组维护一下就ok了. 三元怎么做呢? 把二元的拓展一位就可以了, ...
- HDU 6447 YJJ’s Salesman (树状数组 + DP + 离散)
题意: 二维平面上N个点,从(0,0)出发到(1e9,1e9),每次只能往右,上,右上三个方向移动, 该N个点只有从它的左下方格点可达,此时可获得收益.求该过程最大收益. 分析:我们很容易就可以想到用 ...
- hdu 4991(树状数组+DP)
Ordered Subsequence Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- 【树状数组+dp】HDU 5542 The Battle of Chibi
http://acm.hdu.edu.cn/showproblem.php?pid=5542 [题意] 给定长为n的序列,问有多少个长为m的严格上升子序列? [思路] dp[i][j]表示以a[i]结 ...
- The 2015 China Collegiate Programming Contest -ccpc-c题-The Battle of Chibi(hdu5542)(树状数组,离散化)
当时比赛时超时了,那时没学过树状数组,也不知道啥叫离散化(貌似好像现在也不懂).百度百科--离散化,把无限空间中无限的个体映射到有限的空间中去,以此提高算法的时空效率. 这道题是dp题,离散化和树状数 ...
- HDU 3333 | Codeforces 703D 树状数组、离散化
HDU 3333:http://acm.hdu.edu.cn/showproblem.php?pid=3333 这两个题是类似的,都是离线处理查询,对每次查询的区间的右端点进行排序.这里我们需要离散化 ...
随机推荐
- Android学习备忘笺02Fragment
Android中Fragment可以将UI界面分成多个区块,一般静态或动态添加Fragment. 01.新建Fragment实例 一个Fragment实例包括两个部分:类对象和布局文件(可视化部分). ...
- Objective-C Memory Management 内存管理 2
Objective-C Memory Management 内存管理 2 2.1 The Rules of Cocoa Memory Management 内存管理规则 (1)When you c ...
- Swift protocol extension method is called instead of method implemented in subclass
Swift protocol extension method is called instead of method implemented in subclass protocol MyProto ...
- Swift - 值类型与引用类型的初步探究
前言 swift中的结构体和类在组成和功能上具有一定的相似性.两者都可以含有成员属性.成员方法用于数据存储和功能性模块封装.往往造成不知如何对二者进行区分和使用 值类型概念和引用类型概念 值类型的概念 ...
- new Buffer 生成二进制数据
node编辑环境下: > new Buffer("admin")<Buffer 61 64 6d 69 6e> 通过post请求,服务端接收到是流数据,必须把流数 ...
- [bzoj4816][Sdoi2017]数字表格 (反演+逆元)
(真不想做莫比乌斯了) 首先根据题意写出式子 ∏(i=1~n)∏(j=1~m)f[gcd(i,j)] 很明显的f可以预处理出来,解决 根据套路分析,我们可以先枚举gcd(i,j)==d ∏(d=1~n ...
- CAD参数绘制线型标注(com接口)
主要用到函数说明: _DMxDrawX::DrawDimRotated 绘制一个线型标注.详细说明如下: 参数 说明 DOUBLE dExtLine1PointX 输入第一条界线的起始点X值 DOUB ...
- docker 入门学习
一 : docker 安装(linux-centos7) 安装docker要求 1.docker只支持在64位cup架构计算机上运行,目前不支持32位cup. 2.建议系统的linux内核版本在3.1 ...
- JavaSE-22 反射
学习要点 反射概念 反射的应用 反射概述 1 反射机制 定义 Java反射机制是指在程序在运行状态中,动态获取信息以及动态调用对象方法的功能. Java反射的动态性质:运行时生成对象实例.运行期间调 ...
- No-5.变量的命名
变量的命名 目标 标识符和关键字 变量的命名规则 0.1 标识符和关键字 1.1 标识符 标示符就是程序员定义的 变量名.函数名 名字 需要有 见名知义 的效果 标示符可以由 字母.下划线 和 数字 ...