• Codeforces 1149C Tree Generator™ 线段树 (看题解)


    Tree Generator™

    两点间的距离为 depth[ u ] + depth[ v ] - 2 * depth[ lca ]

    给的字符串可以看成dfs序, 对于x, y 下标, x < y, 他们的lca的肯定在x - y 之间并且dpeth最小。

    问题转换成a[ x ] - 2 * a[ y ] + a[ z ]的最大值 x <= y <= z, 然后区间合并一下。

    #include<bits/stdc++.h>
    #define LL long long
    #define LD long double
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define fio ios::sync_with_stdio(false); cin.tie(0);
    
    using namespace std;
    
    const int N = 2e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
    template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
    template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
    template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    struct info {
        inline void setVal(int v) {
            ans = -inf;
            mx = mn = v;
            XY = YZ = -v;
        }
        inline void addVal(int v) {
            mx += v; mn += v;
            XY -= v; YZ -= v;
        }
        void print() {
            printf("ans: %d  mx: %d  mn: %d  XY: %d  YZ: %d
    ", ans, mx, mn, XY, YZ);
        }
        int ans, mx, mn, XY, YZ;
    };
    
    info operator + (const info& a, const info& b) {
        info c;
        c.ans = max(a.ans, b.ans);
        chkmax(c.ans, a.mx + b.YZ); chkmax(c.ans, a.XY + b.mx);
        c.mx = max(a.mx, b.mx); c.mn = min(a.mn, b.mn);
        c.XY = max(a.XY, b.XY); chkmax(c.XY, a.mx - 2 * b.mn);
        c.YZ = max(a.YZ, b.YZ); chkmax(c.YZ, b.mx - 2 * a.mn);
        return c;
    }
    
    info Tree[N << 2];
    int lazy[N << 2];
    
    inline void push(int rt) {
        if(lazy[rt]) {
            lazy[rt << 1] += lazy[rt];
            Tree[rt << 1].addVal(lazy[rt]);
            lazy[rt << 1 | 1] += lazy[rt];
            Tree[rt << 1 | 1].addVal(lazy[rt]);
            lazy[rt] = 0;
        }
    }
    
    void build(int *a, int l, int r, int rt) {
        if(l == r) {
            Tree[rt].setVal(a[l]);
            return;
        }
        int mid = l + r >> 1;
        build(a, lson); build(a, rson);
        Tree[rt] = Tree[rt << 1] + Tree[rt << 1 | 1];
    }
    
    void update(int L, int R, int val, int l, int r, int rt) {
        if(R < l || r < L) return;
        if(L <= l && r <= R) {
            Tree[rt].addVal(val);
            lazy[rt] += val;
            return;
        }
        push(rt);
        int mid = l + r >> 1;
        update(L, R, val, lson);
        update(L, R, val, rson);
        Tree[rt] = Tree[rt << 1] + Tree[rt << 1 | 1];
    }
    
    int n, q, a[N];
    char s[N];
    
    int main() {
        scanf("%d%d", &n, &q);
        n = (n - 1) * 2;
        scanf("%s", s + 1);
        for(int i = 1; i <= n; i++)
            a[i] = a[i - 1] + (s[i] == '(' ? 1 : -1);
        build(a, 1, n, 1);
        printf("%d
    ", Tree[1].ans);
        while(q--) {
            int x, y; scanf("%d%d", &x, &y);
            update(x, n, s[x] == ')' ? 2 : -2, 1, n, 1);
            update(y, n, s[y] == ')' ? 2 : -2, 1, n, 1);
            swap(s[x], s[y]);
            printf("%d
    ", Tree[1].ans);
        }
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    vue检查用户名是否重复
    后端注册接口完善
    django添加检查用户名和手机号数量接口
    Vue联调,图片及短信验证码
    swift webView 提出这样的要求你能忍吗?
    iOS 如何给Xcode7项目添加“.pch”文件
    swift 定制自己的Button样式
    Swift 为你的webView定制标题
    swift 如何获取webView的内容高度
    如何在MAC上使用SVN,简单几行命令搞定
  • 原文地址:https://www.cnblogs.com/CJLHY/p/10815626.html
Copyright © 2020-2023  润新知