• CF793F Julia the snail 题解


    一、题目:

    洛谷原题

    codeforces原题

    二、思路:

    这道题的官方题解是分块,在这里提供一种吉司机线段树的做法。

    设所有的传送门为二元组 ((l,r)),询问为二元组 ((a,b))。吉司机线段树上的叶子结点 (i) 存储当询问的 (a=i) 时的答案。

    考虑将所有的询问按照右端点从小到大排序。我们维护一个指针 (p),遇到一个新的询问,就将 (p) 向右移动到新的询问的右端点。并做以下处理:

    对于指针移动过程中遇到的所有 (r),那么对于线段树下标区间为 ([1,l]) 中的、所有大于 (l) 的数,将它的值变为 (r)

    三、代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    #define FILEIN(s) freopen(s, "r", stdin)
    #define FILEOUT(s) freopen(s, "w", stdout)
    #define mem(s, v) memset(s, v, sizeof s)
    
    inline int read(void) {
        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 * 10 + ch - '0'; ch = getchar(); }
        return f * x;
    }
    
    const int MAXN = 100005, INF = 1e8;
    
    int n, m, pre[MAXN], Q, ans[MAXN];
    
    struct Query {
        int l, r, id;
        inline friend bool operator <(const Query &a, const Query &b) {
            return a.r < b.r;
        }
    }q[MAXN];
    
    namespace Segment_Tree_Beat {
    
    #define lson (o << 1)
    #define rson (o << 1 | 1)
    
        int maxx[MAXN << 2], sec[MAXN << 2];
        int L[MAXN << 2], R[MAXN << 2];
        int tag1[MAXN << 2], tag2[MAXN << 2];
    
        inline void pushup(int o) {
            if (maxx[lson] == maxx[rson]) {
                maxx[o] = maxx[lson];
                sec[o] = max(sec[lson], sec[rson]);
            }
            else if (maxx[lson] > maxx[rson]) {
                maxx[o] = maxx[lson];
                sec[o] = max(sec[lson], maxx[rson]);
            }
            else {
                maxx[o] = maxx[rson];
                sec[o] = max(sec[rson], maxx[lson]);
            }
        }
    
        void build(int o, int l, int r) {
            L[o] = l; R[o] = r;
            tag1[o] = tag2[o] = INF;
            if (l == r) {
                maxx[o] = l; sec[o] = -1;
                return;
            }
            int mid = (l + r) >> 1;
            build(lson, l, mid); build(rson, mid + 1, r);
            pushup(o);
        }
    
        inline void change(int o, int v1, int v2) {
            if (maxx[o] < v1) return;
            maxx[o] = v2;
            if (v1 <= tag2[o]) {
                tag1[o] = min(tag1[o], v1);
                tag2[o] = v2;
            }
        }
    
        inline void pushdown(int o) {
            if (tag1[o] != INF) {
                change(lson, tag1[o], tag2[o]);
                change(rson, tag1[o], tag2[o]);
                tag1[o] = tag2[o] = INF;
            }
        }
        inline void update(int o, int ql, int qr, int v1, int v2) {
            if (v1 > maxx[o]) return;
            if (ql <= L[o] && R[o] <= qr && v1 > sec[o]) {
                change(o, v1, v2);
                return;
            }
            pushdown(o);
            int mid = (L[o] + R[o]) >> 1;
            if (ql <= mid) update(lson, ql, qr, v1, v2);
            if (qr > mid) update(rson, ql, qr, v1, v2);
            pushup(o);
        }
        inline int query(int o, int q) {
            if (L[o] == R[o]) return maxx[o];
            pushdown(o);
            int mid = (L[o] + R[o]) >> 1;
            if (q <= mid) return query(lson, q);
            return query(rson, q);
        }
    }
    
    inline void modify(int p) {
        if (!pre[p]) return;
        Segment_Tree_Beat::update(1, 1, pre[p], pre[p], p);
    }
    
    int main() {
        n = read(); m = read();
        for (int i = 1; i <= m; ++ i) {
            int l = read(), r = read();
            if (l == r) continue;
            pre[r] = l;
        }
        Q = read();
        for (int i = 1; i <= Q; ++ i) {
            q[i].l = read(); q[i].r = read();
            q[i].id = i;
        }
        sort(q + 1, q + Q + 1);
        Segment_Tree_Beat::build(1, 1, n);
        int R = 1;
        for (int i = 1; i <= Q; ++ i) {
            while (R < q[i].r) modify(++ R);
            ans[q[i].id] = Segment_Tree_Beat::query(1, q[i].l);
        }
        for (int i = 1; i <= Q; ++ i) printf("%d
    ", ans[i]);
        return 0;
    }
    

  • 相关阅读:
    structs2---OGNL表达式
    六种获取配置properties文件的方法
    java poi导出Excel 总结
    Linux中发布项目的一些命令笔记
    JavaScript 闭包
    常见数据库连接方式
    Docker(五):镜像
    Docker(四):docker的安装
    Ubuntu命令
    Docker(三):Docker的基本概念
  • 原文地址:https://www.cnblogs.com/little-aztl/p/14962103.html
Copyright © 2020-2023  润新知