zoukankan      html  css  js  c++  java
  • SP6779 GSS7

    水题,只是坑点多,(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("
    ------
    ")
    #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
    ",__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
    ", 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
    */
    

  • 相关阅读:
    面试题:链表倒数第k个节点
    面试题:重建二叉树
    面试题:从尾到头打印链表
    面试题:第一个出现的字符位置
    面试题:调整数组顺序
    面试题:有限制条件的求和
    面试题:Fibonacci数列
    面试题:旋转数组的最小数字
    面试题:替换空格
    EndNote8破解版下载安装
  • 原文地址:https://www.cnblogs.com/bingoyes/p/11842037.html
Copyright © 2011-2022 走看看