Codeforces Round #429 (Div. 1) D. Destiny #主席树#

D. Destiny

time limit per test

2.5 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

Once, Leha found in the left pocket an array consisting of n integers, and in the right pocket q queries of the form l r k. If there are queries, then they must be answered. Answer for the query is minimal x such that x occurs in the interval l r strictly more than  times or  - 1 if there is no such number. Help Leha with such a difficult task.

Input

First line of input data contains two integers n and q (1 ≤ n, q ≤ 3·105) — number of elements in the array and number of queries respectively.

Next line contains n integers a1, a2, ..., an (1 ≤ ai ≤ n) — Leha's array.

Each of next q lines contains three integers lr and k (1 ≤ l ≤ r ≤ n, 2 ≤ k ≤ 5) — description of the queries.

Output

Output answer for each query in new line.

Examples

input

4 2
1 1 2 2
1 3 2
1 4 2

output

1
-1

input

5 3
1 2 1 3 2
2 5 3
1 2 3
5 5 2

output

2
1
2

Solution

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn = 3e5 + 10;
int cnt, a[maxn], root[maxn];
struct node { int l, r, sum; } tree[maxn * 40];
vector<int> v;

inline const int read()
{
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
    return x * f;
}

inline int getid(int x)
{
    return (int)(lower_bound(v.begin(), v.end(), x) - v.begin()) + 1;
}

void update(int l, int r, int p, int pre, int& now)
{
    tree[now = ++cnt] = tree[pre];
    tree[now].sum++;
    if (l == r) return;
    int mid = (l + r) >> 1;
    if (p <= mid) update(l, mid, p, tree[pre].l, tree[now].l);
    else update(mid + 1, r, p, tree[pre].r, tree[now].r);
}

int query(int l, int r, int k, int L, int R)
{
    if (tree[R].sum - tree[L].sum <= k) return 0;
    if (l == r) return l;
    int mid = (l + r) >> 1;
    int lres = query(l, mid, k, tree[L].l, tree[R].l);
    return lres ? lres : query(mid + 1, r, k, tree[L].r, tree[R].r);
}

int main()
{
    int n = read(), m = read();
    for (int i = 1; i <= n; i++) v.push_back(a[i] = read());
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    for (int i = 1; i <= n; i++) update(1, n, getid(a[i]), root[i - 1], root[i]);
    while (m--)
    {
        int l = read(), r = read(), k = read();
        int id = query(1, n, (r - l + 1) / k, root[l - 1], root[r]);
        printf("%d\n", id ? v[id - 1] : -1);
    }
    return 0;
}
发布了367 篇原创文章 · 获赞 148 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_35850147/article/details/104080805