zoukankan      html  css  js  c++  java
  • poj3237(树链剖分)

    题目链接:http://poj.org/problem?id=3237

    题目大意:指定一颗树上有3个操作:

    1)询问操作,询问a点和b点之间的路径上最长的那条边的长度(即最大值);

    2)取反操作,将a点和b点之间的路径权值都取相反数;

    3)变化操作,把某条边的权值变成指定的值。

    分析:树链剖分,线段树维护好区间的最大最小值,方便取反操作更新。。。

    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define mod 10007
    #define inf 0x3f3f3f3f
    #define N 100010
    #define FILL(a,b) (memset(a,b,sizeof(a)))
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    struct edge
    {
        int to,next;
        edge(){}
        edge(int to,int next):to(to),next(next){}
    }e[N<<1];
    int head[N<<1],tot;
    int top[N];//top[v]表示v所在的重链的顶端节点
    int fa[N];//父亲节点
    int dep[N];//深度
    int sz[N];//si[v]表示以v为根节点的子树的节点数
    int son[N];//重儿子
    int p[N];//p[v]表示v与其父亲节点的连边在线段树中的位置
    int fp[N];//与p数组相反
    int pos;//所有链构成的线段树总长度
    int mx[N<<2],mn[N<<2],col[N<<2],E[N][3];
    void addedge(int u,int v)
    {
        e[tot]=edge(v,head[u]);
        head[u]=tot++;
    }
    void init()
    {
        tot=0;FILL(head,-1);
        pos=0;FILL(son,-1);
    }
    void dfs(int u,int f,int d)
    {
        dep[u]=d;sz[u]=1;fa[u]=f;
        for(int i=head[u];~i;i=e[i].next)
        {
            int v=e[i].to;
            if(v==f)continue;
            dfs(v,u,d+1);
            sz[u]+=sz[v];
            if(son[u]==-1||sz[son[u]]<sz[v])son[u]=v;
        }
    }
    void getpos(int u,int sp)
    {
        top[u]=sp;
        p[u]=++pos;
        fp[pos]=u;
        if(son[u]==-1)return;
        getpos(son[u],sp);
        for(int i=head[u];~i;i=e[i].next)
        {
            int v=e[i].to;
            if(v!=son[u]&&v!=fa[u])
            {
                getpos(v,v);
            }
        }
    }
    void Pushup(int rt)
    {
        int ls=rt<<1,rs=ls|1;
        mx[rt]=max(mx[ls],mx[rs]);
        mn[rt]=min(mn[ls],mn[rs]);
    }
    void Pushdown(int rt)
    {
        int ls=rt<<1,rs=ls|1;
        if(col[rt])
        {
            mx[ls]=-mx[ls];
            mn[ls]=-mn[ls];
            swap(mx[ls],mn[ls]);
            mx[rs]=-mx[rs];
            mn[rs]=-mn[rs];
            swap(mx[rs],mn[rs]);
            col[ls]^=1;col[rs]^=1;
            col[rt]=0;
        }
    }
    void update(int L,int R,int c,int l,int r,int rt)
    {
        if(L<=l&&r<=R)
        {
            if(c!=inf)
            {
                mx[rt]=mn[rt]=c;
                col[rt]=0;
            }
            else
            {
                col[rt]^=1;
                mx[rt]=-mx[rt];
                mn[rt]=-mn[rt];
                swap(mn[rt],mx[rt]);
            }
            return;
        }
        Pushdown(rt);
        int m=(l+r)>>1;
        if(L<=m)update(L,R,c,lson);
        if(m<R)update(L,R,c,rson);
        Pushup(rt);
    }
    int query(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)
            return mx[rt];
        Pushdown(rt);
        int m=(l+r)>>1;
        int res=-inf;
        if(L<=m)res=max(res,query(L,R,lson));
        if(m<R)res=max(res,query(L,R,rson));
        return res;
    }
    int lca(int u,int v,int flag)
    {
        int fu=top[u],fv=top[v];
        int res=-inf;
        while(fu!=fv)
        {
            if(dep[fu]<dep[fv])
            {
                swap(fu,fv);
                swap(u,v);
            }
            if(flag)res=max(res,query(p[fu],p[u],1,pos,1));
            else update(p[fu],p[u],inf,1,pos,1);
            u=fa[fu];fu=top[u];
        }
        if(dep[u]>dep[v])swap(u,v);
        if(u!=v)
        {
            if(flag)res=max(res,query(p[son[u]],p[v],1,pos,1));
            else update(p[son[u]],p[v],inf,1,pos,1);
        }
        return res;
    }
    int main()
    {
        int T,n,u,v;
        scanf("%d",&T);
        while(T--)
        {
            init();
            scanf("%d",&n);
            for(int i=1;i<n;i++)
            {
                scanf("%d%d%d",&E[i][0],&E[i][1],&E[i][2]);
                addedge(E[i][0],E[i][1]);
                addedge(E[i][1],E[i][0]);
            }
            dfs(1,0,0);
            getpos(1,1);
            for(int i=1;i<n;i++)
            {
                if(dep[E[i][0]]>dep[E[i][1]])
                    swap(E[i][0],E[i][1]);
                update(p[E[i][1]],p[E[i][1]],E[i][2],1,pos,1);
            }
            char op[10];
            while(1)
            {
                scanf("%s",op);
                if(op[0]=='D')break;
                scanf("%d%d",&u,&v);
                if(op[0]=='Q')
                    printf("%d
    ",lca(u,v,1));
                else if(op[0]=='N')lca(u,v,0);
                else update(p[E[u][1]],p[E[u][1]],v,1,pos,1);
            }
        }
    }
    View Code
  • 相关阅读:
    Network (poj1144)
    C. Hongcow Builds A Nation
    ZYB loves Xor I(hud5269)
    D. Chloe and pleasant prizes
    Game(hdu5218)
    约瑟夫环的递推方法
    Misaki's Kiss again(hdu5175)
    Exploration(hdu5222)
    B. Arpa's weak amphitheater and Mehrdad's valuable Hoses
    C. Arpa's loud Owf and Mehrdad's evil plan
  • 原文地址:https://www.cnblogs.com/lienus/p/4242801.html
Copyright © 2011-2022 走看看