• HDU 3237 Tree(树链剖分)(线段树区间取反,最大值)


    Tree
    Time Limit: 5000MS   Memory Limit: 131072K
    Total Submissions: 9123   Accepted: 2411

    Description

    You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbered 1 through N − 1. Each edge is associated with a weight. Then you are to execute a series of instructions on the tree. The instructions can be one of the following forms:

    CHANGE i v Change the weight of the ith edge to v
    NEGATE a b Negate the weight of every edge on the path from a to b
    QUERY a b Find the maximum weight of edges on the path from a to b

    Input

    The input contains multiple test cases. The first line of input contains an integer t (t ≤ 20), the number of test cases. Then follow the test cases.

    Each test case is preceded by an empty line. The first nonempty line of its contains N (N ≤ 10,000). The next N − 1 lines each contains three integers a, b and c, describing an edge connecting nodes a and b with weight c. The edges are numbered in the order they appear in the input. Below them are the instructions, each sticking to the specification above. A lines with the word “DONE” ends the test case.

    Output

    For each “QUERY” instruction, output the result on a separate line.

    Sample Input

    1
    
    3
    1 2 1
    2 3 2
    QUERY 1 2
    CHANGE 1 3
    QUERY 1 2
    DONE

    Sample Output

    1
    3
    【分析】题意很好理解,唯一的难点就是将某一区间内的数变成相反数,需要用到懒惰标记。
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <time.h>
    #include <string>
    #include <map>
    #include <stack>
    #include <vector>
    #include <set>
    #include <queue>
    #define met(a,b) memset(a,b,sizeof a)
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    typedef long long ll;
    const int N=2e5+50;
    const int M=N*N+10;
    int dep[N],siz[N],fa[N],id[N],son[N],val[N],top[N]; //top 最近的重链父节点
    int num,s,m,n,q;
    int sum[N*2],tre[2*N];
    int maxn[N],minn[N],lazy[N];
    vector<int> v[N];
    struct tree {
        int x,y,val;
        void read() {
            scanf("%d%d%d",&x,&y,&val);
        }
    } e[N];
    void dfs1(int u, int f, int d) {
        dep[u] = d;
        siz[u] = 1;
        son[u] = 0;
        fa[u] = f;
        for (int i = 0; i < v[u].size(); i++) {
            int ff = v[u][i];
            if (ff == f) continue;
            dfs1(ff, u, d + 1);
            siz[u] += siz[ff];
            if (siz[son[u]] < siz[ff])
                son[u] = ff;
        }
    }
    void dfs2(int u, int tp) {
        top[u] = tp;
        id[u] = ++num;
        if (son[u]) dfs2(son[u], tp);
        for (int i = 0; i < v[u].size(); i++) {
            int ff = v[u][i];
            if (ff == fa[u] || ff == son[u]) continue;
            dfs2(ff, ff);
        }
    }
    void ChangeVal(int rt) {
        int tmp=maxn[rt];
        maxn[rt]=-minn[rt];
        minn[rt]=-tmp;
    }
    void Push_up(int rt) {
        maxn[rt]=max(maxn[2*rt],maxn[2*rt+1]);
        minn[rt]=min(minn[2*rt],minn[2*rt+1]);
    }
    void Push_down(int rt) {
        if(lazy[rt]) {
            lazy[rt]^=1;
            lazy[2*rt]^=1;
            ChangeVal(rt*2);
            lazy[2*rt+1]^=1;
            ChangeVal(2*rt+1);
        }
    }
    void change(int t,int l,int r,int x,int v){
        if(l==r) maxn[t]=minn[t]=v;
        else{
            Push_down(t);
            int mid=(l+r)>>1;
            if(x<=mid) change(t*2,l,mid,x,v);
            else change(t*2+1,mid+1,r,x,v);
            Push_up(t);
        }
    }
    void  Build(int l,int r,int rt) {
        if(l==r) {
            maxn[rt]=minn[rt]=val[l];
            return;
        }
        int m=(l+r)>>1;
        Build(lson);
        Build(rson);
        Push_up(rt);
        //printf("rt=%d sum[rt]=%d
    ",rt,sum[rt]);
    }
    
    void Update(int L,int R,int l,int r,int rt) {
        if(l>=L&&r<=R) {
            lazy[rt]^=1;
            ChangeVal(rt);
            return;
        }
        Push_down(rt);
        int m=(r+l)>>1;
        if(L<=m)Update(L,R,lson);
        if(R>m) Update(L,R,rson);
        Push_up(rt);
    }
    
    int Query(int L,int R,int l,int r,int rt) {
        if(L<=l&&r<=R)return maxn[rt];
        Push_down(rt);
        int m=(l+r)>>1;
        if(R<=m)return Query(L,R,lson);
        else if(L>m)return Query(L,R,rson);
        else return max(Query(L,m,lson),Query(m+1,R,rson));
    }
    
    void solve(int u, int v) {
        int tp1 = top[u], tp2 = top[v];
        int ans = 0;
        while (tp1 != tp2) {
            if (dep[tp1] < dep[tp2]) {
                swap(tp1, tp2);
                swap(u, v);
            }
            Update(id[tp1],id[u],1,n,1);
            u = fa[tp1];
            tp1 = top[u];
        }
        if (u == v) return;
        if (dep[u] > dep[v]) swap(u, v);
        Update(id[son[u]],id[v],1,n,1);
        return;
    }
    int Yougth(int u,int v) {
        int tp1 = top[u], tp2 = top[v];
        int ans=-10000000;
        while (tp1 != tp2) {
            if (dep[tp1] < dep[tp2]) {
                swap(tp1, tp2);
                swap(u, v);
            }
            ans = max(Query(id[tp1], id[u],1,n,1),ans);
            u = fa[tp1];
            tp1 = top[u];
        }
        if (u == v) return ans;
        if (dep[u] > dep[v]) swap(u, v);
        ans = max(Query(id[son[u]], id[v],1,n,1),ans);
        return ans;
    }
    void Clear(int n) {
        for(int i=1; i<=n; i++)
            v[i].clear();
        met(son,0);met(maxn,0);met(minn,0);
        met(lazy,0);
    }
    int main() {
        int t;
        scanf("%d",&t);
        while(t--) {
            scanf("%d",&n);
            Clear(n);
            int u,vv,w;
            for(int i=1; i<n; i++) {
                e[i].read();
                v[e[i].x].push_back(e[i].y);
                v[e[i].y].push_back(e[i].x);
            }
            num = 0;
            dfs1(1,0,1);
            dfs2(1,1);
            for (int i = 1; i < n; i++) {
                if (dep[e[i].x] < dep[e[i].y]) swap(e[i].x, e[i].y);
                val[id[e[i].x]] = e[i].val;
            }
            Build(1,num,1);
            char str[20];
            while(~scanf("%s",str)) {
                if(str[0]=='D')break;
                if(str[0]=='C') {
                    scanf("%d%d",&u,&vv);
                    if(dep[e[u].x]<dep[e[u].y])swap(e[u].x,e[u].y);
                    change(1,1,n,id[e[u].x],vv);
                } else if(str[0]=='N'){
                    scanf("%d%d",&u,&vv);
                    solve(u,vv);
                }else {
                    scanf("%d%d",&u,&vv);
                    if(u==vv)puts("0");
                    else printf("%d
    ",Yougth(u,vv));
                }
            }
    
        }
    
        return 0;
    }
  • 相关阅读:
    接口测试基础
    python学习笔记(一)
    Charles学习笔记
    接口测试笔记
    【CSS】Beginner5:Margins&Padding
    【CSS】Beginner4:Text
    【CSS】Beginner3:Color
    【CSS】Beginner2:Selectors, Properties, and Values
    【CSS】Beginner1:Applying CSS
    【HTML】Beginner9:Form
  • 原文地址:https://www.cnblogs.com/jianrenfang/p/6357857.html
Copyright © 2020-2023  润新知