hdu 3450 离散化+dp+线段树优化
来源:互联网 发布:hadoop结构化数据存储 编辑:程序博客网 时间:2024/05/31 05:28
链接:http://acm.hdu.edu.cn/showproblem.php?pid=3450
题意:
给你一串长度为n的序列,给一个d,要求找出有几个子序列能够满足两个相邻的元素之间差值不超过d。
思路:
dp。定义dp[i]表示以第i个为结束的满足条件的子序列的个数。
转移方程:
答案就是dp数组的总和最后扣掉n就可以了。
此时会发现更新的时间复杂度是
转移的复杂度是
但是这里又有一个问题,就是这个a[i]的值是在int 范围内的,也就是说这个线段树要开
这时候又该想到离散化处理,因为我们只需要有这个值之间的相互关系。对于具体的值并不是太有用,将每一个数对应一个id,因为只有n个数,这样就将
查找出a[i]-d、a[i]+d的id,然后查询这个区间的和用来更新dp[i]。 再查询出a[i]的id,将dp[i]+1更新到线段树之中去。
离散化处理:
可以将原来的元素序列复制一份为id数组,排序去重,之后运用二分查找来查询离散化后的id。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define M 100009#define mod 9901int n,d;int dat[M<<2];int dp[M];int id[M];int b[M];void pushup(int rt){ dat[rt] = (dat[rt<<1] + dat[rt<<1|1])%mod;}void build(int l,int r,int rt){ if(l == r) { dat[rt] = 0; return ; } int mid = (l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); pushup(rt);}void update(int a,int b,int l,int r,int rt){ if(l == r) { dat[rt] = (dat[rt]+b)%mod; return ; } int mid = (l+r)>>1; if(a <= mid) update(a,b,l,mid,rt<<1); else update(a,b,mid+1,r,rt<<1|1); pushup(rt);}int query(int a,int b,int l,int r,int rt){ if(a <= l && r <= b) { return dat[rt]; } int ret = 0; int mid = (l+r)>>1; if(a <= mid) ret = (ret+query(a,b,l,mid,rt<<1))%mod; if(b > mid) ret = (ret+query(a,b,mid+1,r,rt<<1|1))%mod; return ret%mod;}int main(){ while(scanf("%d %d",&n,&d) == 2) { for(int i = 1;i <= n;i++) { scanf("%d",&b[i]); id[i] = b[i]; //复制id数组 } sort(id+1,id+n+1); int m = unique(id+1,id+n+1) - (id+1); build(1,m,1); int ans = 0; for(int i = 1;i <= n;i++) { int l = lower_bound(id+1,id+m+1,b[i]-d) - id; //查询b[i]-d 所在的id int r = upper_bound(id+1,id+m+1,b[i]+d) - id - 1; //查询b[i]+d 所在的id //这里用upper 是因为lower可能会找到刚刚好的,也可能会找到大的,避免这个直接用upper 后 -1 就行了 dp[i] = query(l,r,1,m,1); int temp = lower_bound(id+1,id+m+1,b[i]) - id; //查询b[i] 所在的id, update(temp,(dp[i]+1)%mod,1,m,1); ans = (ans+dp[i])%mod; } printf("%d\n",ans%mod); } return 0;}
0 0
- hdu 3450 离散化+dp+线段树优化
- 【dp+离散化+线段树优化】Paint
- HDU 3607 线段树+离散化+DP
- UESTC 1501 - Defense Lines 离散化+线段树优化DP
- codeforces 271E 离散化+线段树,dp优化
- HDU 2836 Traversal(线段树+离散化+DP)
- HDU 3016 Man Down(线段树+离散化+dp)
- NOIP模拟题 [递推][优化][dp][线段树][离散]
- zoj 3349 Special Subsequence 【离散化二分 + 线段树优化dp】
- codeforces #343 div2 D. Babaei and Birthday Cake(DP+离散化+线段树优化)
- HDU 2227 Find the nondecreasing subsequences(线段树+离散化+DP)
- hdu(4325)线段树+离散化+lazy
- HDU 4325 离散化 + 线段树
- HDU 4828 Coder(线段树 + 离散化)
- hdu 4325 Flowers(线段树+离散化)
- HDU 4288 线段树+离散化
- hdu 4325 Flowers(离散化+线段树)
- hdu 2528(离散化线段树)
- 12222222222222222222222222222
- 黑马程序员——Java之内部类
- 排序算法一览
- leetcode_3sum closet
- 工厂模式
- hdu 3450 离散化+dp+线段树优化
- UIPageControl, UIScrollView属性及UIScrollViewDelegate详解
- 获取 Activity 的返回参数
- Android 热更新——非侵入AOP框架
- iOS唯一表示符获取方案
- 计算机网络面试题
- 上海Spark Meetup第六次聚会
- 【内容建设】以DEDECMS为例,讲解站内文章编辑的一些注意点,有益无害
- 找工作C++面试资料之问答题整理(1)