SPOJ375 Query on a tree

Posted Soda

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SPOJ375 Query on a tree相关的知识,希望对你有一定的参考价值。

https://vjudge.net/problem/SPOJ-QTREE

题意:

一棵树,每条边有个权值

两种操作

一个修改每条边权值

一个询问两点之间这一条链的最大边权

点数<=10000

多组测试数据,case<=20

Example

Input:
1

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

Output:
1
3
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=210000;
const int inf=0x3fffffff;
int son[N],father[N],sz[N],head[N],num;
int ti[N],idx,dep[N],top[N];
struct edge{
    int ed,nxt;
}e[N*3];
struct Edge{
    int x,y,v;
}E[N*2];
int max(int a,int b){
    if(a>b)return a;
    return b;
}
void addedge(int x,int y){
    e[++num].ed=y;e[num].nxt=head[x];head[x]=num;
    e[++num].ed=x;e[num].nxt=head[y];head[y]=num;
}

void dfs_find(int u,int fa){//处理每棵子树大小和重儿子 
    sz[u]=1;dep[u]=dep[fa]+1;son[u]=0;father[u]=fa;
    for(int i=head[u];i;i=e[i].nxt){
        int v=e[i].ed;
        if(v==fa)continue;
        dfs_find(v,u);
        sz[u]+=sz[v];
        if(sz[son[u]]<sz[v])son[u]=v;
    }
}
void dfs_time(int u,int fa){
    ti[u]=idx++;
    top[u]=fa;
    if(son[u]!=0)dfs_time(son[u],top[u]);//处理同重链上点的top 
    for(int i=head[u];i;i=e[i].nxt){
        int v=e[i].ed;
        if(v==father[u]||v==son[u])continue;//枚举到了同一重链上的点就跳过 
        dfs_time(e[i].ed,e[i].ed);
    }
}

struct tree{
    int l,r,v;
}T[N<<2];
void buildtree(int l,int r,int id){
    T[id].l=l;T[id].r=r;T[id].v=-inf;
    if(l==r)return;
    int mid=(l+r)>>1;
    buildtree(l,mid,id*2);
    buildtree(mid+1,r,id*2+1);
}
void update(int id,int cp,int v){
    if(T[id].l==T[id].r){T[id].v=v;return;}
    int mid=(T[id].l+T[id].r)>>1;
    if(mid>=cp)update(id*2,cp,v);
    if(mid<cp)update(id*2+1,cp,v);
    T[id].v=max(T[id*2].v,T[id*2+1].v);
}
int query(int l,int r,int id){
    if(T[id].r==r&&T[id].l==l)return T[id].v;
    int mid=(T[id].l+T[id].r)>>1;
    if(mid>=r)return query(l,r,id*2);
    else if(mid<l)return query(l,r,id*2+1);
    else return max(query(l,mid,id*2),query(mid+1,r,id*2+1));
}
int lca(int x,int y){
    int ans=-inf;
    while(top[x]!=top[y]){
        if(dep[top[x]]<dep[top[y]])swap(x,y);
        ans=max(ans,query(ti[top[x]],ti[x],1));
        x=father[top[x]];
    }
    if(dep[x]>dep[y])swap(x,y);
    if(x!=y)ans=max(ans,query(ti[x]+1,ti[y],1));
    return ans;
}
int main(){
    int n,t,x,y,v,j;
    char str[100];
    scanf("%d",&t);
    while(t--){
        memset(head,0,sizeof(head));
        num=0;scanf("%d",&n);
        for(int i=1;i<n;i++){
            scanf("%d%d%d",&E[i].x,&E[i].y,&E[i].v);
            addedge(E[i].x,E[i].y);
        }
        dep[1]=0;sz[0]=0;idx=1;
        dfs_find(1,1);
        dfs_time(1,1);
        buildtree(2,n,1);
        for(int i=1;i<n;i++){
            if(dep[E[i].x]<dep[E[i].y])swap(E[i].x,E[i].y);
            update(1,ti[E[i].x],E[i].v);
        }
        while(true){
            scanf("%s",str);
            if(str[0]==D)break;
            else if(str[0]==Q){
                scanf("%d%d",&x,&y);
                printf("%d\n",lca(x,y));
            }
            else if(str[0]==C){
                scanf("%d%d",&j,&v);
                update(1,ti[E[j].x],v);
            }
        }
    }
    return 0;
}

 

以上是关于SPOJ375 Query on a tree的主要内容,如果未能解决你的问题,请参考以下文章

spoj 375 Query on a tree (树链剖分)

[SPOJ 375]Query on a tree

[spoj 375]QTREE - Query on a tree[树链剖分]

SPOJ 375 Query on a tree

「SPOJ1487」Query on a tree III

SPOJ QTREE - Query on a tree