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
#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
#define PLI pair
#define PII pair
#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\n", 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\n", 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\n", Tree[1].ans);
    }
    return 0;
}

/*
*/

 

转载于:https://www.cnblogs.com/CJLHY/p/10815626.html

你可能感兴趣的:(Codeforces 1149C Tree Generator™ 线段树 (看题解))