[hdu5247]rmq+预处理
题意:有一个无序数组,求有多少个长度为k的区间满足把区间内的数排序后是连续的。
思路:长度为k的区间排序后是 连续的数等价于maxval-minval等于k-1并且不同的数有k个(或者说没有相同的数),第一个条件可以用rmq快速得到区间最大值与最小值之差,第二个条件可以这样求,按区间的左边界分类预处理,遍历右边界,如果[L,R]内有相同的数,则[L,R+k]有相同的数,否则转化为判断a[R+1]是否在区间[L,R]内出现过,维护一个last数组,last[i]表示i上一次出现的位置,那么等价于判断last[a[R+1]]是否>=L,由于a[i]很大,所以需离散后处理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <vector> using namespace std; typedef long long LL; #define all(a) (a).begin(), (a).end() const int maxn = 1e4 + 7; struct ST { struct Node { int a[22]; int &operator [] ( int x) { return a[x]; } }; const static int maxn = 1e6 + 7; vector<Node> dp; static int index[maxn]; static void init_index() { index[1] = 0; for ( int i = 2; i < maxn; i ++) { index[i] = index[i - 1]; if (!(i & (i - 1))) index[i] ++; } } void init_min(vector< int > &a) { int n = a.size(); dp.resize(n); for ( int i = 0; i < n; i ++) dp[i][0] = a[i]; for ( int j = 1; (1 << j) <= n; j ++) { for ( int i = 0; i + (1 << j) - 1 < n; i ++) { dp[i][j] = min(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]); } } } void init_max(vector< int > &a) { int n = a.size(); dp.resize(n); for ( int i = 0; i < n; i ++) dp[i][0] = a[i]; for ( int j = 1; (1 << j) <= n; j ++) { for ( int i = 0; i + (1 << j) - 1 < n; i ++) { dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]); } } } int query_min( int L, int R) { int p = index[R - L + 1]; return min(dp[L][p], dp[R - (1 << p) + 1][p]); } int query_max( int L, int R) { int p = index[R - L + 1]; return max(dp[L][p], dp[R - (1 << p) + 1][p]); } }; int ST::index[maxn]; ST st1, st2; vector< int > a, b; bool chk[maxn][1000]; int last[maxn]; int main() { #ifndef ONLINE_JUDGE freopen ( "in.txt" , "r" , stdin); #endif // ONLINE_JUDGE puts ( "Case #1:" ); int n, m; cin >> n >> m; a.resize(n); for ( int i = 0; i < n; i ++) { scanf ( "%d" , &a[i]); } b = a; ST::init_index(); st1.init_max(a); st2.init_min(a); sort(all(a)); a.erase(unique(all(a)), a.end()); for ( int i = 0; i < n; i ++) { b[i] = lower_bound(all(a), b[i]) - a.begin(); } for ( int i = 0; i < n; i ++) { chk[i][1] = true ; memset (last, 0xff, sizeof (last)); last[b[i]] = i; for ( int L = 2; i + L - 1 < n && L <= 1000; L ++) { if (last[b[i + L - 1]] >= i) break ; last[b[i + L - 1]] = i + L - 1; chk[i][L] = true ; } } for ( int i = 0; i < m; i ++) { int k; scanf ( "%d" , &k); int ans = 0; for ( int i = 0; i + k - 1 < n; i ++) { ans += st1.query_max(i, i + k - 1) - st2.query_min(i, i + k - 1) == k - 1 && chk[i][k]; } printf ( "%d\n" , ans); } return 0; } |
[hdu5247]rmq+预处理的更多相关文章
- I. Max answer(RMQ预处理前缀和)
题目链接: https://nanti.jisuanke.com/t/38228 题目大意:给你n个数,让你找出一个区间中f的最大值,具体的f计算方法,这段区间的和乘以这段区间的最小值. 具体思路:我 ...
- [HDOJ5726]GCD(RMQ,二分)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5726 题意:给定数列,求区间[L,R]的GCD的值,并求出有多少个子区间满足和[L,R]的GCD相等. ...
- [数据结构]RMQ问题小结
RMQ问题小结 by Wine93 2014.1.14 1.算法简介 RMQ问题可分成以下2种 (1)静态RMQ:ST算法 一旦给定序列确定后就不在更新,只查询区间最大(小)值!这类问题可以用倍增 ...
- hdu 3948(后缀数组+RMQ)
题意:求一个串中有多少不同的回文串. 分析:这一题的关键是如何去重,我表示我现在还没理解为什么这样去重,先放这里过两天再看!! //不同回文子串数目 #include <iostream> ...
- ural 1297(后缀数组+RMQ)
题意:就是让你求一个字符串中的最长回文,如果有多个长度相等的最长回文,那就输出第一个最长回文. 思路:这是后缀数组的一种常见的应用,首先把原始字符串倒转过来,然后接在原始字符串的后面,中间用一个不可能 ...
- HDU 5726 GCD (RMQ + 二分)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5726 给你n个数,q个询问,每个询问问你有多少对l r的gcd(a[l] , ... , a[r]) ...
- POJ 4003 Bob’s Race && HDU4123 Bob’s Race (dfs+rmq)
Bob’s Race Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 378 Accepted: 119 Descript ...
- 树形DP+RMQ+尺取法 hdu4123
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4123 参考博客:两种解法-树形dp+二分+单调队列(或RMQ)-hdu-4123-Bob’s Race ...
- HDU 4123 Bob’s Race(RMQ)
题意是说给出一棵树,N(10^5)个顶点,以及每条边的权值,现在需要选择连续的K个点(顶点编号连续),可以被选出来的条件是: 若d[i]代表顶点i到树上其他点的距离的最大值,使得区间[a, b]的d值 ...
随机推荐
- CVE 2019-0708 漏洞复现+
PART 1 参考链接:https://blog.csdn.net/qq_42184699/article/details/90754333 漏洞介绍: 当未经身份验证的攻击者使用 RDP 连接到目标 ...
- Java类的使用
在一个Java文件中写两个类:一个基本的类,一个测试类.注意:文件名称和测试类名称一致. 如何使用呢?创建对象使用.如何创建对象呢?格式:类名 对象名 = new 类名(); Student s = ...
- 负载均衡服务之HAProxy基础配置(四)
前文我们聊了haproxy的状态页配置,状态页中显示各参数的含义,以及基于cookie做会话保持的配置,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12776 ...
- Ubuntu下的eclipse配置MapReduce
下载配置文件: 链接:https://pan.baidu.com/s/13vatPHpDP5HaW0mKuHydUA提取码:pjxi 1)启动hadoop cd /usr/local/hadoop . ...
- Centos史上新版最详细步骤-Linux无脑命令式oracle11g静默安装
1. 关闭selinux 1.1 sed -i "s/SELINUX=enforcing/SELINUX=disabled/" /etc/selinux/config 1.2 或者 ...
- NC使用练习之通达OA-2017版本漏洞复现后续
利用上一篇通达OA的漏洞环境,练习NC工具的使用. 步骤: 1.本机启动nc.exe监听端口: 确认端口是否成功监听成功: 2.用冰蝎将nc.exe上传至目标机: 3.用命令行在目标机启动nc.exe ...
- udp协议与tcp协议
TCP协议与UDP协议支持的应用协议 TCP支持的应用协议主要有:Telnet.FTP.SMTP等: UDP支持的应用层协议主要有:NFS(网络文件系统).SNMP(简单网络管理协议).DNS(主域名 ...
- 徐州I
#include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=a;i<=b;++i) #defi ...
- Python2 和 Python3的区别
Python2 和 Python3的区别: 1.python2的默认编码方式是ascii码:python3的默认编码是utf-8. 如果出现乱码或者编码错误,可以使用以下编码在文件头来指定编码: #- ...
- 【Linux常见命令】route命令
route - show / manipulate the IP routing table route命令用于显示和操作IP路由表. route命令用来显示并设置Linux内核中的网络路由表,rou ...