zoukankan      html  css  js  c++  java
  • CF840D Destiny(主席树)

    左转弱化版:https://www.cnblogs.com/zcr-blog/p/12736587.html

    题目描述

    题解

    和弱化版的思路一样,如果左子树中出现的次数大于要求,则左子树中就可能存在答案,右子树同理否则输出$-1$即可。

    这里要求最小值所以优先找左子树即可。

    这样做的单次查询复杂度是$O(k log{n})$的,$k$很小,肯定能过。

    #include <iostream>
    #include <cstdio>
    using namespace std;
    const int N = 300010;
    struct Segment{
        int lson, rson, val;
    }tr[N * 30];
    int tot;
    int n, m;
    int a[N], rt[N];
    void ins(int &cur, int pre, int l, int r, int pos, int v) {
        cur = ++tot;
        tr[cur] = tr[pre];
        tr[cur].val += v;
        if (l == r) return;
        int mid = (l + r) >> 1;
        if (pos <= mid) ins(tr[cur].lson, tr[pre].lson, l, mid, pos, v);
        else ins(tr[cur].rson, tr[pre].rson, mid + 1, r, pos, v); 
    }
    bool ask(int x, int y, int l, int r, int k) {
        if (l == r) {
            printf("%d
    ", l);
            return true;
        }
        int mid = (l + r) >> 1;
        if (tr[tr[y].lson].val - tr[tr[x].lson].val > k) {
            if (ask(tr[x].lson, tr[y].lson, l, mid, k)) return true;
        }
        if (tr[tr[y].rson].val - tr[tr[x].rson].val > k) {
            if (ask(tr[x].rson, tr[y].rson, mid + 1, r, k)) return true;
        }
        return false;
    }
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            ins(rt[i], rt[i - 1], 1, n, a[i], 1);
        }
        while (m--) {
            int l, r, k;
            scanf("%d%d%d", &l, &r, &k);
            k = (r - l + 1) / k;
            if (!ask(rt[l - 1], rt[r], 1, n, k)) puts("-1");
        }
        return 0;
    }
  • 相关阅读:
    任务框架--Quartz 配置文件
    地址和值
    线性基学习笔记
    S07
    如何在实际项目中使用PageHelper分页插件
    设计模式:原型模式
    常用JS代码片段
    Thomson Plaza里面的三家店以及水果大会
    13.搜索过滤
    07-多线程
  • 原文地址:https://www.cnblogs.com/zcr-blog/p/12795539.html
Copyright © 2011-2022 走看看