zoukankan      html  css  js  c++  java
  • 多校 1010 Taotao Picks Apples(补题)

    》》点击进入原题《《

     思路:题解很有意思,适合线段树进阶 

    考虑每次修改不叠加,因此我们可以从如何对原序列进行预处理着手。
    通过观察可以发现,将原序列从任意位置断开,我们可以通过分别维护左右段的某些信息来拼接
    得到答案。
    对于左段来说:

    • 需要知道最大值的位置,以及到达最大值需要几步;
    • 使用 ST 维护信息。
    对于右段来说:
    • 由于前半部分的信息未知,因此我们需要维护从每个位置开始到结尾可以走几步;
    • 从后往前做 DP,每次找出右边第一个比自己大的数,答案就是它的 DP 值 +1。
    对于每次询问:
    • 考虑这个数左边的部分加上这个数之后的答案和最大值;
    • 再找到右边第一个大于左半部分最大值的数,答案相加即可。
    预处理使用 ST 表,每次查询需要一个二分,总复杂度 O(nlogn+qlogn)。 —题解来自HDU

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    #define lson l,m,o<<1
    #define rson m+1,r,o<<1|1
    
    const int maxn = 1e5 + 10;
    int a[maxn], d1[maxn], d2[maxn];
    int tree[maxn << 2], vis[maxn << 2];
    int ans, cur;
    
    void build(int l, int r, int o){
        if (l == r){
            tree[o] = a[l];
            vis[o] = l;
            return;
        }
        int m = (l + r) >> 1;
        build(lson);
        build(rson);
        tree[o] = max(tree[o << 1], tree[o << 1 | 1]);
        if (tree[o << 1] >= tree[o << 1 | 1])
            vis[o] = vis[o << 1];
        else vis[o] = vis[o << 1 | 1];
    
    }
    void query(int l, int r, int o, int ql, int qr, int k){
        if (l == r){
            if (tree[o]>k)
                cur = min(cur, l);
            return;
        }
        int m = (l + r) >> 1;
        if (l >= ql&&r <= qr){
            if (tree[o << 1] > k)
                query(lson, ql, qr, k);
            else if (tree[o << 1 | 1] > k)
                query(rson, ql, qr, k);
            return;
        }
        if (ql <= m)
            query(lson, ql, qr, k);
        if (qr > m)query(rson, ql, qr, k);
    }
    void query1(int l, int r, int o, int ql, int qr){
        if (l >= ql&&r <= qr){
            if (tree[o] > a[cur])
                cur = vis[o];
            return;
        }
        int m = (l + r) >> 1;
        if (ql <= m)query1(lson, ql, qr);
        if (qr > m)query1(rson, ql, qr);
    }
    int main(){
        ios::sync_with_stdio(false);
    
        int t; cin >> t;
        while (t--){
            int n, m, p, q, Max = 0;
            cin >> n >> m;
            for (int i = 1; i <= n; i++){
                cin >> a[i];
                if (a[i] > Max)
                    d1[i] = d1[i - 1] + 1, Max = a[i];
                else d1[i] = d1[i - 1];
            }
            build(1, n, 1);
            for (int i = n; i; i--){
                cur = n + 1;
                query(1, n, 1, i, n, a[i]);
                if (cur > n)cur = 0;
                d2[i] = d2[cur] + 1;
            }
            while (m--){
                cin >> p >> q;
                ans = cur = 0;
                if (p != 1){
                    query1(1, n, 1, 1, p - 1);
                }
                ans += d1[cur];
                if (q > a[cur])ans++;
                else q = a[cur];
                cur = n + 1;
    
                if (p != n)query(1, n, 1, p + 1, n, q);
                if (cur <= n)ans += d2[cur];
                cout << ans << endl;
            }
        }
    }
  • 相关阅读:
    D. Babaei and Birthday Cake--- Codeforces Round #343 (Div. 2)
    Vijos P1389婚礼上的小杉
    AIM Tech Round (Div. 2) C. Graph and String
    HDU 5627Clarke and MST
    bzoj 3332 旧试题
    codeforces 842C Ilya And The Tree
    codesforces 671D Roads in Yusland
    Travelling
    codeforces 606C Sorting Railway Cars
    codeforces 651C Watchmen
  • 原文地址:https://www.cnblogs.com/zengguoqiang/p/9506601.html
Copyright © 2011-2022 走看看