Sign on Fence CodeForces - 484E

Sign on Fence CodeForces - 484E

题意:

给你一个长度为n的数组, 有q次询问,每次询问, 问你在 l到r的区间子串长度为 w 的最小值最大为多少?

题解:

A:这题怎么二分答案。

A:能详细一点吗?

B: 这题问你在区间 l到r里面子串长度为w的最小值最大, 那么这个答案一定是这数组里面的某一个值, 假设我们可以建n颗线段树, 每课线段树的含义为:第课线段树 将大于等于a[i]的值看成1, 小于a[i]的值赋值为0, 如果答案是a[i]就查第i颗线段树 的l到r区间是否有连续1de个数大于等于w, 如果存在 答案就像大一点走,反之向小一点的走, 这样就可以用二分了。

A: 也就是主席树维护区间线段树?

B: 是的!

 #include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 7;

int a[N], n, q, top = 1, rt[N];
#define m (l + r) / 2

vector<pair<int, int> > v;


struct hjt {
    int l, r, sum;
    int lone, rone;
    int len;
}tree[24 * N];

bool cmp(pair<int,int> x, pair<int, int> y) {
    return x.first > y.first;
}

void push_up(int node) {
    if (tree[tree[node].l].len == tree[tree[node].l].lone) {
        tree[node].lone = tree[tree[node].l].len + tree[tree[node].r].lone;
    } else {
        tree[node].lone = tree[tree[node].l].lone;
    }
    if (tree[tree[node].r].len == tree[tree[node].r].rone) {
        tree[node].rone = tree[tree[node].r].len + tree[tree[node].l].rone;
    } else {
        tree[node].rone = tree[tree[node].r].rone;
    }
    tree[node].sum = max(tree[node].lone, tree[node].rone);
    tree[node].sum = max(tree[node].sum, tree[tree[node].l].rone + tree[tree[node].r].lone);
    tree[node].sum = max(tree[node].sum, max(tree[tree[node].l].sum, tree[tree[node].r].sum));
}

void update(int pos, int last, int &now, int l, int r) {
    now = top++;
    tree[now] = tree[last];
    tree[now].len = r - l + 1;
    tree[last].len = r - l + 1;
    if (l == r) {
        tree[now].sum = 1;
        tree[now].lone = tree[now].rone = 1;
        return;
    }
    if (pos <= m) update(pos, tree[last].l, tree[now].l, l, m);
    else update(pos, tree[last].r, tree[now].r, m + 1, r);
    push_up(now);
}

hjt merg(hjt x, hjt y) {
    hjt z;

    if (x.len == 0) return y;
    if (x.len == x.lone) {
        z.lone = x.len + y.lone;
    } else {
        z.lone = x.lone;
    }
    if (y.rone == y.len) {
        z.rone = y.len + x.rone;
    } else {
        z.rone = y.rone;
    }
    z.len = x.len + y.len;
    z.sum = max(z.lone, z.rone);
    z.sum = max(x.rone + y.lone, z.sum);
    z.sum = max(z.sum, max(x.sum, y.sum));
    return z;
}

hjt query(int now, int ql, int qr, int l, int r) {
    if (ql <= l && qr >= r) {
        return tree[now];
    }
    hjt ans;
    ans.l = ans.len = ans.lone = ans.rone = ans.r = ans.sum = 0;
    if(ql <= m) ans = merg(ans, query(tree[now].l, ql, qr, l, m));
    if(qr > m) ans = merg(ans, query(tree[now].r, ql, qr, m + 1, r));
    return ans;
}



int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        v.push_back({a[i], i});
    }
    sort(v.begin(), v.end(), cmp);
    for (int i = 0; i < n; i++) {
        update(v[i].second, rt[i], rt[i + 1], 1, n);
    }
    scanf("%d", &q);
    while (q--) {
        int ql, qr, w;
        scanf("%d %d %d", &ql, &qr, &w);
        int l = 1, r = n, ans = 0;
        while (l <= r) {
            if (query(rt[m], ql, qr, 1, n).sum >= w) {
                ans = m; 
                r = m - 1;
            } else {
                l = m + 1;
            }
        }
        printf("%d\n", v[ans - 1].first);
    }



}
posted @ 2020-07-11 13:57  ccsu_zhaobo  阅读(93)  评论(0)    收藏  举报