• [POJ 3237] Tree


    Tree
     

    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 ab 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

    树链剖分模板题、好吧、我又逗比了,最开始初始化为-1,但是由于有负数的存在,所以一直不对、、受不了、总是改不了马虎的习惯

    用线段树维护一个最大值和最小值。

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <queue>
    #include <cmath>
    #include <map>
    #include <iterator>
    #include <cstring>
    #include <string>
    using namespace std;
    #define INF 0x7fffffff
    #define ll long long
    #define N 100010
    
    struct Edge2
    {
        int a,b,c;
    }s[N<<1];
    
    struct Edge
    {
        int to,next;
    }edge[N<<1];
    int head[N],tot;
    
    int num[N];
    int pos;
    int fa[N];
    int son[N];
    int p[N];
    int fp[N];
    int deep[N];
    int size[N];
    int top[N];
    int n;
    
    void init()
    {
        tot=0;
        pos=1;
        memset(head,-1,sizeof(head));
        memset(son,-1,sizeof(son));
    }
    void add(int x,int y)
    {
        edge[tot].to=y;
        edge[tot].next=head[x];
        head[x]=tot++;
    }
    void dfs1(int now,int pre,int d)
    {
        deep[now]=d;
        fa[now]=pre;
        size[now]=1;
        for(int i=head[now];i!=-1;i=edge[i].next)
        {
            int next=edge[i].to;
            if(next!=pre)
            {
                dfs1(next,now,d+1);
                size[now]+=size[next];
                if(son[now]==-1 || size[next]>size[son[now]])
                {
                    son[now]=next;
                }
            }
        }
    }
    void dfs2(int now,int tp)
    {
        top[now]=tp;
        p[now]=pos++;
        fp[p[now]]=now;
        if(son[now]==-1) return;
        dfs2(son[now],tp);
        for(int i=head[now];i!=-1;i=edge[i].next)
        {
            int next=edge[i].to;
            if(next!=son[now]&&next!=fa[now])
            {
                dfs2(next,next);
            }
        }
    }
    int mx[N<<2];
    int mi[N<<2];
    int col[N<<2];
    void pushup(int rt)
    {
        mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
        mi[rt]=min(mi[rt<<1],mi[rt<<1|1]);
    }
    void pushdown(int rt)
    {
        if(col[rt])
        {
            col[rt<<1]^=1;
            col[rt<<1|1]^=1;
            mx[rt<<1]=-mx[rt<<1];
            mi[rt<<1]=-mi[rt<<1];
            swap(mx[rt<<1],mi[rt<<1]);
            mx[rt<<1|1]=-mx[rt<<1|1];
            mi[rt<<1|1]=-mi[rt<<1|1];
            swap(mx[rt<<1|1],mi[rt<<1|1]);
            col[rt]=0;
        }
    }
    void build(int l,int r,int rt)
    {
        col[rt]=0;
        if(l==r)
        {
            mi[rt]=mx[rt]=num[fp[l]];
            return;
        }
        int m=(l+r)>>1;
        build(l,m,rt<<1);
        build(m+1,r,rt<<1|1);
        pushup(rt);
    }
    void update(int l,int r,int rt,int pos,int val)
    {
        if(l==r)
        {
            mi[rt]=mx[rt]=val;
            return;
        }
        pushdown(rt);
        int m=(l+r)>>1;
        if(pos<=m) update(l,m,rt<<1,pos,val);
        else update(m+1,r,rt<<1|1,pos,val);
        pushup(rt);
    }
    void update2(int l,int r,int rt,int L,int R)
    {
        if(l==L && R==r)
        {
            mx[rt]=-mx[rt];
            mi[rt]=-mi[rt];
            swap(mx[rt],mi[rt]);
            col[rt]^=1;
            return;
        }
        pushdown(rt);
        int m=(l+r)>>1;
        if(R<=m) update2(l,m,rt<<1,L,R);
        else if(L>m) update2(m+1,r,rt<<1|1,L,R);
        else
        {
            update2(l,m,rt<<1,L,m);
            update2(m+1,r,rt<<1|1,m+1,R);
        }
        pushup(rt);
    }
    int query(int l,int r,int rt,int L,int R)
    {
        if(l==L && r==R)
        {
            return mx[rt];
        }
        pushdown(rt);
        int m=(l+r)>>1,ans=-INF;
        if(L>m) return ans=max(ans,query(m+1,r,rt<<1|1,L,R));
        else if(R<=m) ans=max(ans,query(l,m,rt<<1,L,R));
        else return ans=max(ans,max(query(l,m,rt<<1,L,m),query(m+1,r,rt<<1|1,m+1,R)));
        return ans;
    }
    int convert(int pos)
    {
        int a=s[pos].a;
        int b=s[pos].b;
        if(deep[a]>deep[b]) return a;
        return b;
    }
    void pre_solve()
    {
        memset(num,-1,sizeof(num));
        for(int i=1;i<n;i++)
        {
            num[convert(i)]=s[i].c;
        }
    }
    void change2(int x,int y)
    {
        int f1=top[x];
        int f2=top[y];
        while(f1!=f2)
        {
            if(deep[f1]<deep[f2])
            {
                swap(x,y);
                swap(f1,f2);
            }
            update2(1,n,1,p[f1],p[x]);
            x=fa[f1];
            f1=top[x];
        }
        if(x==y) return;
        if(deep[x]>deep[y]) swap(x,y);
        update2(1,n,1,p[x]+1,p[y]);
    }
    int change(int x,int y)
    {
        int ans=-INF;
        int f1=top[x];
        int f2=top[y];
        while(f1!=f2)
        {
            if(deep[f1]<deep[f2])
            {
                swap(x,y);
                swap(f1,f2);
            }
            ans=max(ans,query(1,n,1,p[f1],p[x]));
            x=fa[f1];
            f1=top[x];
        }
        if(x==y) return ans;
        if(deep[x]>deep[y]) swap(x,y);
        ans=max(ans,query(1,n,1,p[x]+1,p[y]));
        return ans;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            init();
            scanf("%d",&n);
            for(int i=1;i<n;i++)
            {
                scanf("%d%d%d",&s[i].a,&s[i].b,&s[i].c);
                add(s[i].a,s[i].b);
                add(s[i].b,s[i].a);
            }
            dfs1(1,0,0);
            dfs2(1,1);
            pre_solve();
            build(1,n,1);
            while(1)
            {
                int a,b;
                char op[10];
                scanf("%s",op);
                if(op[0]=='D') break;
                scanf("%d%d",&a,&b);
                if(op[0]=='C')
                {
                    a=convert(a);
                    update(1,n,1,p[a],b);
                }
                else if(op[0]=='N')
                {
                    change2(a,b);
                }
                else
                {
                    printf("%d
    ",change(a,b));
                }
            }
        }
        return 0;
    }
    趁着还有梦想、将AC进行到底~~~by 452181625
  • 相关阅读:
    【ROM修改教程】添加高级电源重启菜单(安卓4.0.4官方ROM)
    MTK 快速开机 技术详解
    MT6592 经验积累
    Android系统之Broadcom GPS 移植
    Android关机流程源码分析
    Android 4.1.2系统添加重启功能
    android4.2添加重启菜单项
    MTK平台 Android4.0.3 定制关机动画
    不进化,则消亡——互联网时代企业管理的十项实践
    前端切图:调用百度地图API
  • 原文地址:https://www.cnblogs.com/hate13/p/4118462.html
Copyright © 2020-2023  润新知