CSU1553 Good subsequence —— 二分 + RMQ/线段树
来源:互联网 发布:鸿图网络危机公关公司 编辑:程序博客网 时间:2024/06/06 03:34
题目链接: http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1553
Description
Give you a sequence of n numbers, and a number k you should find the max length of Good subsequence. Good subsequence is a continuous subsequence of the given sequence and its maximum value - minimum value<=k. For example n=5, k=2, the sequence ={5, 4, 2, 3, 1}. The answer is 3, the good subsequence are {4, 2, 3} or {2, 3, 1}.
Input
There are several test cases.
Each test case contains two line. the first line are two numbers indicates n and k (1<=n<=10,000, 1<=k<=1,000,000,000). The second line give the sequence of n numbers a[i] (1<=i<=n, 1<=a[i]<=1,000,000,000).
The input will finish with the end of file.
Output
For each the case, output one integer indicates the answer.
Sample Input
5 25 4 2 3 11 11
Sample Output
31
题解:
之前学了RMQ,线段树, 树状数组,但是一直不知道他们在哪里能派上用场。通过这题,终于找到他们的用武之地了:区间查询最大最小值。
解决了查询区间最大最小值的问题,剩下的就是二分了。这里是二分长度。
RMQ:
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <string>#include <vector>#include <map>#include <set>#include <queue>#include <sstream>#include <algorithm>using namespace std;#define pb push_back#define mp make_pair#define ms(a, b) memset((a), (b), sizeof(a))//#define LOCAL#define eps 0.0000001#define LNF (1<<60)typedef long long LL;const int inf = 0x3f3f3f3f;const int maxn = 10000+10;const int mod = 1e9+7;LL st_max[maxn][16], st_min[maxn][16];LL a[maxn];void RMQ_init(int n){ for(int i = 0; i<n; i++) { st_min[i][0] = a[i]; st_max[i][0] = a[i]; } for(int j = 1; (1<<j)<=n; j++)//枚举长度 for(int i = 0; i+(1<<j)-1<n; i++)//枚举起点 { st_min[i][j] = min(st_min[i][j-1],st_min[i+(1<<(j-1))][j-1]); st_max[i][j] = max(st_max[i][j-1],st_max[i+(1<<(j-1))][j-1]); }}LL RMQ(int l, int r)//查询{ int k = 0; while((1<<(k+1))<=r-l+1) k++; return max(st_max[l][k],st_max[r-(1<<k)+1][k]) - min(st_min[l][k],st_min[r-(1<<k)+1][k]);}int test(int len, int n, int k){ for(int i = len-1; i<n; i++) if(RMQ(i-len+1, i)<=1LL*k) return 1; return 0;}int main(){#ifdef LOCAL freopen("input.txt", "r", stdin);// freopen("output.txt", "w", stdout);#endif // LOCAL int n, k; while(~scanf("%d%d", &n, &k)) { for(int i=0;i<n;i++) scanf("%lld", &a[i]); ms(st_max, 0); ms(st_min, 0); RMQ_init(n); int l = 1, r = n; while(l<=r) { int mid = (l+r)/2; if(test(mid, n, k)) l = mid+1; else r = mid-1; } printf("%d\n", r); } return 0;}
线段树:
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <string>#include <vector>#include <map>#include <set>#include <queue>#include <sstream>#include <algorithm>using namespace std;#define pb push_back#define mp make_pair#define ms(a, b) memset((a), (b), sizeof(a))//#define LOCAL#define eps 0.0000001#define LNF 1000000000000typedef long long LL;const int inf = 0x3f3f3f3f;const int maxn = 10000+10;const int mod = 1e9+7;LL st_max[4*maxn], st_min[4*maxn];LL a[maxn];void build(int rt, int l, int r){ if(l==r) { st_max[rt] = a[r]; st_min[rt] = a[r]; return; } int mid = (l+r)>>1; build(rt*2,l,mid); build(rt*2+1,mid+1,r); st_max[rt] = max(st_max[rt*2], st_max[rt*2+1]); st_min[rt] = min(st_min[rt*2], st_min[rt*2+1]);}//由于最大最小值都要查询,而return只能返回一个,所以用ma和mi记录最小值LL query(int rt, int l, int r, int x, int y, LL &ma, LL &mi){ if(x<=l && y>=r) { ma = max(ma,st_max[rt]); mi = min(mi,st_min[rt]); return ma - mi; } int mid = (l+r)>>1; if(y<=mid) query(rt*2,l,mid,x,y,ma,mi); else if(x>=mid+1) query(rt*2+1,mid+1,r,x,y,ma,mi); else query(rt*2,l,mid,x,mid,ma,mi),query(rt*2+1,mid+1,r,mid+1,y,ma,mi); return ma - mi;}int test(int len, int n, int k){ for(int i = len-1; i<n; i++) { LL ma = -LNF, mi = LNF; if(query(1,0,n-1, i-len+1, i, ma,mi)<=1LL*k) return 1; } return 0;}int main(){#ifdef LOCAL freopen("input.txt", "r", stdin);// freopen("output.txt", "w", stdout);#endif // LOCAL int n, k; while(scanf("%d%d", &n, &k)!=EOF) { for(int i=0;i<n;i++) scanf("%lld", &a[i]); build(1,0,n-1); int l = 1, r = n; while(l<=r) { int mid = (l+r)/2; if(test(mid, n,k)) l = mid+1; else r = mid-1; } printf("%d\n", r); } return 0;}
- CSU1553 Good subsequence —— 二分 + RMQ/线段树
- CSU 1553-Good subsequence(RMQ)
- CF 6E Exposition(RMQ | 线段树,二分)
- codeforces 487B B. Strip(rmq+线段树+二分)
- 胜者树(线段树RMQ)——Luogu1816 忠诚
- POJ3264 【RMQ基础题—ST-线段树】
- poj3368(线段树,RMQ)
- 线段树/RMQ问题
- 线段树RMQ
- VJ16216/RMQ/线段树
- 线段树求RMQ
- 线段树 Circular RMQ
- 线段树和rmq
- poj 3419 Difference Is Beautiful (dp+二分+RMQ或者dp+离线线段树)
- 2016 多校第一场 hdu 5276((线段树+暴力打表)|(RMQ + 二分))
- HDU 5726 GCD (rmq+二分 or 线段树 维护区间gcd)
- zoj 3349 Special Subsequence 【离散化二分 + 线段树优化dp】
- sicily 1800 线段树RMQ
- nc 远程控制
- 欢迎使用CSDN-markdown编辑器
- QT 的 串口接收的数据 QByteArray 类怎么得到16进制
- #掉过的坑#cocos:无法打开文件libcurl_img.lib
- Spring常见Bean总结,必需学习的类
- CSU1553 Good subsequence —— 二分 + RMQ/线段树
- READONLY You can't write against a read only slave.
- Leetcode-List-Hash
- 深入浅出Mybatis-分页
- ILSpy反编译软件的使用
- vue非父子通信
- 名片扫一扫识别OCR技术
- 真正从零开始,TensorFlow详细安装入门图文教程!
- SVM三重境界