SP6779 GSS7 - Can you answer these queries VII(线段树,树链剖分)

水题,只是坑点多,\(tag\)\(0\)时可能也要\(pushdown\),所以要\(bool\)标记是否需要。最后树链剖分询问时注意线段有向!!!

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <numeric>
#define R(a,b,c) for(register int a = (b); a <= (c); ++a)
#define nR(a,b,c) for(register int a = (b); a >= (c); --a)
#define Swap(a,b) ((a) ^= (b) ^= (a) ^= (b))
#define MP make_pair
#ifdef QWQ
#define D_e_Line printf("\n------\n")
#define D_e(x) cerr << (#x) << " " << x << endl
#define C_e(x) cout << (#x) << " " << x << endl
#define FileOpen() freopen("in.txt", "r", stdin)
#define FileSave() freopen("out.txt", "w", stdout)
#define Pause() system("pause")
#include <cassert>
#define PASS fprintf(stderr, "Passing [%s] in LINE %d\n",__FUNCTION__,__LINE__)
#else
#define D_e_Line
#define D_e(x)
#define C_e(x)
#define FileOpen()
#define FileSave()
#define Pause()
#define PASS
#endif
using namespace std;
struct FastIO {
    template<typename ATP> inline FastIO& operator >> (ATP &x) {
        x = 0; int sign = 1; char c;
        for(c = getchar(); c < '0' || c > '9'; c = getchar()) if(c == '-') sign = -1;
        while(c >= '0' && c <= '9') x = x * 10 + (c ^ '0'), c = getchar();
        if(sign == -1) x = -x;
        return *this;
    }
} io;
template<typename ATP> inline ATP Max(ATP x, ATP y) {
    return x > y ? x : y;
}
template<typename ATP> inline ATP Min(ATP x, ATP y) {
    return x < y ? x : y;
}
template<typename ATP> inline ATP Abs(ATP x) {
    return x < 0 ? -x : x;
}
#include <vector>
const int N = 2e5 + 7;
struct Edge {
    int nxt, pre;
} e[N << 1];
int head[N], cntEdge;
inline void add(int u, int v) {
    e[++cntEdge] = (Edge){ head[u], v}, head[u] = cntEdge;
}
int fa[N], son[N], siz[N], dep[N], dfn[N], dfnIdx, top[N], rnk[N], val[N], n;
void DFS_First(int u, int father) {
    dep[u] = dep[father] + 1, fa[u] = father, siz[u] = 1;
    for(register int i = head[u]; i; i = e[i].nxt){
        int v = e[i].pre;
        if(v == father) continue;
        DFS_First(v, u);
        siz[u] += siz[v];
        if(siz[v] > siz[son[u]]) son[u] = v;
    }
}
void DFS_Second(int u, int Tp) {
    top[u] = Tp, dfn[u] = ++dfnIdx, rnk[dfnIdx] = u;
    if(!son[u]) return;
    DFS_Second(son[u], Tp);
    for(register int i = head[u]; i; i = e[i].nxt){
        int v = e[i].pre;
        if(v != fa[u] && v != son[u]) DFS_Second(v, v);
    }
}
struct Seg {
    int sum, val, pre, suf, tag;
    bool flag;
    Seg() {sum = val = pre = suf = tag = flag = 0;}
    Seg operator + (const Seg &b) const {
        Seg c;
        c.sum = sum + b.sum;
        c.val = Max(Max(val, b.val), suf + b.pre);
        c.pre = Max(pre, sum + b.pre);
        c.suf = Max(b.suf, b.sum + suf);
        return c;
    }
} t[N << 2];
#define ls rt << 1
#define rs rt << 1 | 1
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
inline void Pushup(int &rt) {
    t[rt] = t[ls] + t[rs];
}
inline void Pushdown(int &rt, int l, int mid, int r) {
    t[ls].sum = (mid - l + 1) * t[rt].tag;
    t[rs].sum = (r - mid) * t[rt].tag;
    t[ls].pre = t[ls].val = t[ls].suf = Max(t[ls].sum, 0);
    t[rs].pre = t[rs].val = t[rs].suf = Max(t[rs].sum, 0);
    t[ls].flag = t[rs].flag = true;
    t[ls].tag = t[rs].tag = t[rt].tag;
    t[rt].tag = 0;
    t[rt].flag = false;
}
void Build(int rt, int l, int r) {
    if(l == r){
        t[rt].sum = val[rnk[l]];
        t[rt].val = t[rt].pre = t[rt].suf = Max(t[rt].sum, 0);
        return;
    }
    int mid = (l + r) >> 1;
    Build(lson), Build(rson);
    Pushup(rt);
}
void Updata(int rt, int l, int r, int L, int R, int w) {
    if(L <= l && r <= R){
        t[rt].sum = (r - l + 1) * w;
        t[rt].pre = t[rt].suf = t[rt].val = Max(t[rt].sum, 0);
        t[rt].tag = w;
        t[rt].flag = true;
        return;
    }
    int mid = (l + r) >> 1;
    if(t[rt].flag) Pushdown(rt, l, mid, r);
    if(L <= mid) Updata(lson, L, R, w);
    if(R > mid) Updata(rson, L, R, w);
    Pushup(rt);
}
Seg Query(int rt, int l, int r, int L, int R) {
    if(L <= l && r <= R) return t[rt];
    int mid = (l + r) >> 1;
    if(t[rt].flag) Pushdown(rt, l, mid, r);
    Seg s;
    if(L <= mid) s = Query(lson, L, R);
    if(R > mid) s = s + Query(rson, L, R);
    return s;
}
inline void Updata(int x, int y, int w) {
    while(top[x] != top[y]){
        if(dep[top[x]] < dep[top[y]]) Swap(x, y);
        Updata(1, 1, n, dfn[top[x]], dfn[x], w);
        x = fa[top[x]];
    }
    if(dep[x] < dep[y]) Swap(x, y);
    Updata(1, 1, n, dfn[y], dfn[x], w);
}
//inline int Query(int x, int y) {
//  Seg s;
//  while(top[x] != top[y]){
//      if(dep[top[x]] < dep[top[y]]) Swap(x, y);
//      s = s + Query(1, 1, n, dfn[top[x]], dfn[x]);
//      x = fa[top[x]];
//  }
//  if(dep[x] < dep[y]) Swap(x, y);
//  Swap(s.suf, s.pre);
//  return (s + Query(1, 1, n, dfn[y], dfn[x])).val;
//}
inline int Query(int x, int y) {
    Seg L, R;
    while(top[x] != top[y]){
        if(dep[top[x]] < dep[top[y]]){
            R = Query(1, 1, n, dfn[top[y]], dfn[y]) + R;
            y = fa[top[y]];
        }
        else{
            L = Query(1, 1, n, dfn[top[x]], dfn[x]) + L;
            x = fa[top[x]];
        }
    }
    if(dep[x] > dep[y]){
        L = Query(1, 1, n, dfn[y], dfn[x]) + L;
    }
    else{
        R = Query(1, 1, n, dfn[x], dfn[y]) + R;
    }
    Swap(L.pre, L.suf);
    return (L + R).val;
}
int main() {
//FileOpen();
//FileSave();
    io >> n;
    R(i,1,n) io >> val[i];
    R(i,2,n){
        int u, v;
        io >> u >> v;
        add(u, v);
        add(v, u);
    }
    DFS_First(1, 0);
    DFS_Second(1, 1);
    Build(1, 1, n);
    int m;
    io >> m;
    while(m--){
        int opt, l, r, w;
        io >> opt >> l >> r;
        if(opt == 1){
            printf("%d\n", Query(l, r));
        }
        else{
            io >> w;
            Updata(l, r, w);
        }
    }
    
    return 0;
}
/*
13
9 4 12 18 19 1 11 18 16 5 1 10 9 2 1
3 1
4 1
5 1
6 4
7 3
8 3
9 3
10 8
11 9
12 10
13 10
5
2 1 10 10
2 7 13 6
1 5 9
1 4 10
1 9 10
*/

猜你喜欢

转载自www.cnblogs.com/bingoyes/p/11842037.html