zoukankan      html  css  js  c++  java
  • 【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;
    }
  • 相关阅读:
    js 兼容阻止事件冒泡stopPropagation
    php session cookie
    js 给父元素的每个子元素绑定事件
    php 调用系统命令 超时
    php textarea换行
    php 中文字符串截取子串
    Predefined Asp.net skins(Themes) 你下载了吗?
    自定义DataFilter实现Atlas客户端DataView的数据筛选
    用Altas Behaviors实现就地编辑(1) [译]
    组件开发之Asp.net服务器控件Collection[集合]属性的设计时支持--编辑、保存
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6189406.html
Copyright © 2011-2022 走看看