• 【POJ3237】Tree 树链剖分+线段树


    【POJ3237】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
    题解:树剖+线段树裸题,其中取相反数的操作就是把最大值和最小值交换在分别取相反数就好了
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #define lson x<<1
    #define rson x<<1|1
    using namespace std;
    typedef long long ll;
    const int maxn=10010;
    int n,cnt,tot;
    int sm[maxn<<2],sn[maxn<<2],tag[maxn<<2];
    int to[maxn<<1],next[maxn<<1],val[maxn<<1],v[maxn],u[maxn],fa[maxn],head[maxn];
    int deep[maxn],size[maxn],son[maxn],p[maxn],top[maxn];
    char str[10];
    int readin()
    {
        int ret=0,sig=1;    char gc;
        while(gc<'0'||gc>'9')    sig=(gc=='-')?-1:1,gc=getchar();
        while(gc>='0'&&gc<='9')    ret=ret*10+gc-'0',gc=getchar();
        return ret*sig;
    }
    void add(int a,int b,int c)
    {
        to[cnt]=b;
        val[cnt]=c;
        next[cnt]=head[a];
        head[a]=cnt++;
    }
    void dfs1(int x)
    {
        size[x]=1;
        for(int i=head[x];i!=-1;i=next[i])
        {
            if(to[i]!=fa[x])
            {
                fa[to[i]]=x;
                u[to[i]]=val[i];
                deep[to[i]]=deep[x]+1;
                dfs1(to[i]);
                size[x]+=size[to[i]];
                if(size[to[i]]>size[son[x]])    son[x]=to[i];
            }
        }
    }
    void dfs2(int x,int tp)
    {
        top[x]=tp;
        p[x]=++tot;
        v[p[x]]=u[x];
        if(son[x])    dfs2(son[x],tp);
        for(int i=head[x];i!=-1;i=next[i])
            if(to[i]!=son[x]&&to[i]!=fa[x])
                dfs2(to[i],to[i]);
    }
    void pushup(int x)
    {
        sm[x]=max(sm[lson],sm[rson]);
        sn[x]=min(sn[lson],sn[rson]);
    }
    void pushdown(int x)
    {
        if(tag[x])
        {
            swap(sm[lson],sn[lson]),swap(sm[rson],sn[rson]);
            sm[lson]=-sm[lson],sn[lson]=-sn[lson],sm[rson]=-sm[rson],sn[rson]=-sn[rson];
            tag[lson]^=1,tag[rson]^=1;
            tag[x]=0;
        }
    }
    void build(int l,int r,int x)
    {
        if(l==r)
        {
            sm[x]=sn[x]=v[l];
            return ;
        }
        int mid=l+r>>1;
        build(l,mid,lson),build(mid+1,r,rson);
        pushup(x);
    }
    void updata(int l,int r,int x,int a,int b)
    {
        if(l==r)
        {
            sm[x]=sn[x]=b;
            return ;
        }
        pushdown(x);
        int mid=l+r>>1;
        if(a<=mid)    updata(l,mid,lson,a,b);
        else    updata(mid+1,r,rson,a,b);
        pushup(x);
    }
    void upgate(int l,int r,int x,int a,int b)
    {
        if(a<=l&&r<=b)
        {
            tag[x]^=1;
            swap(sm[x],sn[x]);
            sm[x]=-sm[x],sn[x]=-sn[x];
            return ;
        }
        pushdown(x);
        int mid=l+r>>1;
        if(b<=mid)    upgate(l,mid,lson,a,b);
        else if(a>mid)    upgate(mid+1,r,rson,a,b);
        else    upgate(l,mid,lson,a,b),upgate(mid+1,r,rson,a,b);
        pushup(x);
    }
    int query(int l,int r,int x,int a,int b)
    {
        if(a<=l&&r<=b)    return sm[x];
        pushdown(x);
        int mid=l+r>>1;
        if(b<=mid)    return query(l,mid,lson,a,b);
        if(a>mid)    return query(mid+1,r,rson,a,b);
        return max(query(l,mid,lson,a,b),query(mid+1,r,rson,a,b));
    }
    void change()
    {
        int x=readin(),y=readin();
        updata(1,n,1,max(p[to[x*2-2]],p[to[x*2-1]]),y);
    }
    void fan()
    {
        int x=readin(),y=readin();
        while(top[x]!=top[y])
        {
            if(deep[top[x]]<deep[top[y]])    swap(x,y);
            upgate(1,n,1,p[top[x]],p[x]);
            x=fa[top[x]];
        }
        if(deep[x]>deep[y])    swap(x,y);
        if(x!=y)    upgate(1,n,1,p[x]+1,p[y]);
    }
    void getmax()
    {
        int x=readin(),y=readin(),ans=1<<31;
        while(top[x]!=top[y])
        {
            if(deep[top[x]]<deep[top[y]])    swap(x,y);
            ans=max(ans,query(1,n,1,p[top[x]],p[x]));
            x=fa[top[x]];
        }
        if(deep[x]>deep[y])    swap(x,y);
        if(x!=y)    ans=max(ans,query(1,n,1,p[x]+1,p[y]));
        printf("%d
    ",ans);
    }
    void work()
    {
        n=readin();
        memset(head,-1,sizeof(head));
        memset(son,0,sizeof(son));
        memset(fa,0,sizeof(fa));
        memset(tag,0,sizeof(tag));
        cnt=tot=0;
        int i,a,b,c;
        for(i=1;i<n;i++)
        {
            a=readin(),b=readin(),c=readin();
            add(a,b,c),add(b,a,c);
        }
        deep[1]=1;
        dfs1(1);
        dfs2(1,1);
        build(1,n,1);
        while(scanf("%s",str))
        {
            switch(str[0])
            {
                case 'C':change();    break;
                case 'N':fan();    break;
                case 'Q':getmax();    break;
                case 'D':return ;
            }
        }
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)    work();
        return 0;
    }
  • 相关阅读:
    多线程创建方式及线程安全问题
    JDBC连接池&DBUtils
    mySQL 多表查询语句
    git 本机链接多库配置
    mysql类似递归的一种操作进行层级查询
    js 自定义事件观察者模式(发布/订阅)
    CSS样式遇见的问题总结记录
    maven打包pom.xml备忘
    JasperReports实现报表调出excel
    ActiveMQ 集群配置 高可用
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6189406.html
Copyright © 2020-2023  润新知