题意:有一个无序数组,求有多少个长度为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+预处理的更多相关文章

  1. I. Max answer(RMQ预处理前缀和)

    题目链接: https://nanti.jisuanke.com/t/38228 题目大意:给你n个数,让你找出一个区间中f的最大值,具体的f计算方法,这段区间的和乘以这段区间的最小值. 具体思路:我 ...

  2. [HDOJ5726]GCD(RMQ,二分)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5726 题意:给定数列,求区间[L,R]的GCD的值,并求出有多少个子区间满足和[L,R]的GCD相等. ...

  3. [数据结构]RMQ问题小结

    RMQ问题小结 by Wine93 2014.1.14   1.算法简介 RMQ问题可分成以下2种 (1)静态RMQ:ST算法 一旦给定序列确定后就不在更新,只查询区间最大(小)值!这类问题可以用倍增 ...

  4. hdu 3948(后缀数组+RMQ)

    题意:求一个串中有多少不同的回文串. 分析:这一题的关键是如何去重,我表示我现在还没理解为什么这样去重,先放这里过两天再看!! //不同回文子串数目 #include <iostream> ...

  5. ural 1297(后缀数组+RMQ)

    题意:就是让你求一个字符串中的最长回文,如果有多个长度相等的最长回文,那就输出第一个最长回文. 思路:这是后缀数组的一种常见的应用,首先把原始字符串倒转过来,然后接在原始字符串的后面,中间用一个不可能 ...

  6. HDU 5726 GCD (RMQ + 二分)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5726 给你n个数,q个询问,每个询问问你有多少对l r的gcd(a[l] , ... , a[r]) ...

  7. 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 ...

  8. 树形DP+RMQ+尺取法 hdu4123

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4123 参考博客:两种解法-树形dp+二分+单调队列(或RMQ)-hdu-4123-Bob’s Race ...

  9. HDU 4123 Bob’s Race(RMQ)

    题意是说给出一棵树,N(10^5)个顶点,以及每条边的权值,现在需要选择连续的K个点(顶点编号连续),可以被选出来的条件是: 若d[i]代表顶点i到树上其他点的距离的最大值,使得区间[a, b]的d值 ...

随机推荐

  1. Spark SQL源码剖析(一)SQL解析框架Catalyst流程概述

    Spark SQL模块,主要就是处理跟SQL解析相关的一些内容,说得更通俗点就是怎么把一个SQL语句解析成Dataframe或者说RDD的任务.以Spark 2.4.3为例,Spark SQL这个大模 ...

  2. phpstudy之访问loaclhost显示目录

    phpstudy版本:phpstudy2018 具体操作: 当前版本的默认设置访问网站根目录是不会显示目录的,需要我们设置,其实也很简单,只需两步就可以搞定 1.找到phpstudy目录下的www文件 ...

  3. Unity 游戏框架搭建 2019 (三十二、三十三) 类的命名 & 代码文件命名

    昨天我们完成了第八个示例的第二个 MenuItem 菜单顺序的调整. 我们今天再往下接着调整. 我们来看下接下来的 MenuItem 代码如下: [MenuItem("QFramework/ ...

  4. 原子类的ABA问题

    原子类AtomicInteger的ABA问题 连环套路 从AtomicInteger引出下面的问题 CAS -> Unsafe -> CAS底层思想 -> ABA -> 原子引 ...

  5. react: typescript toastr

    import toastr @types/toastr toastr.ts import * as toastr from "toastr" toastr.option.posit ...

  6. 域名和服务器绑定及https协议更换

    服务器是之前已经购买了的 1.腾讯云产品中搜索域名注册(产品太多了懒得找,直接搜索来得快些) 2.进去之后可以选择各种后缀的域名,输入自己喜欢的,看看哪些后缀是没有被注册的.自己挑选一个就可以,按照指 ...

  7. select和epoll区别

    select.epoll 区别总结: 1.支持一个进程所能打开的最大连接数 select 单个进程所能打开的最大连接数有FD_SETSIZE宏定义,其大小是32个整数的大小(在32位的机器上,大小就是 ...

  8. 日志分析工具ELK(一)

    一.ELK介绍 1.1 elasticsearch 1.1.1 elasticsearch介绍 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎 ...

  9. Netty(七):EventLoop学习前导——Reactor模式

    了解Netty的人多少都会知道Netty的高性能的一个原因就是它是基于事件驱动的,而这一事件的原型就是Reactor模式. 所以在学习EventLoop前,很有必要先搞懂Reactor模式. 本文目录 ...

  10. 自定义View之Canvas使用

    自定义View的绘制流程一般都是这样:提前创建好Paint对象,重写onDraw(),把绘制代码卸载ondraw()里面,大致如下: Paint paint = new Paint(); @Overr ...