Spoj375.Query on a tree——树链剖分+线段树(基于边权)

http://www.spoj.com/problems/QTREE/

模板题贴模板

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=10010;
using namespace std;

struct node{
    int v,next;
}edges[maxn<<1];int tot,head[maxn],n;
inline void addedge(int u,int v){
    edges[tot].next=head[u];
    edges[tot].v=v;
    head[u]=tot++;
}
int dep[maxn],size[maxn],top[maxn],fa[maxn],p[maxn],son[maxn],fp[maxn];
int pos;
void Init(){
    memset(son,-1,sizeof(son));
    memset(head,-1,sizeof(head));
    tot=pos=0;
}
void dfs1(int u,int pre,int d){
    dep[u]=d;
    fa[u]=pre;
    size[u]=1;
    for(int i=head[u];i!=-1;i=edges[i].next){
        int v=edges[i].v;
        if(v!=pre){
            dfs1(v,u,d+1);
            size[u]+=size[v];
            if(son[u]==-1||size[son[u]]<size[v]) son[u]=v;
        }
    }
}
void getpos(int u,int sp){
    top[u]=sp;
    p[u]=pos++;
    fp[p[u]]=u;
    if(son[u]==-1) return ;
    getpos(son[u],sp);
    for(int i=head[u];i!=-1;i=edges[i].next){
        int v=edges[i].v;
        if(v!=son[u]&&v!=fa[u]) getpos(v,v);
    }
}
int mx[maxn<<2];
void push_up(int rt){
    mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
}
void update(int p,int v,int l,int r,int rt){
    if(l==r){
        mx[rt]=v;
        return ;
    }
    int m=(l+r)>>1;
    if(p<=m) update(p,v,lson);
    else update(p,v,rson);
    push_up(rt);
}
int query(int L,int R,int l,int r,int rt){
    if(L<=l&&r<=R){
        return mx[rt];
    }
    int m=(l+r)>>1;
    int ans=-1;
    if(L<=m) ans=max(ans,query(L,R,lson));
    if(m<R) ans=max(ans,query(L,R,rson));
    return ans;
}
int find(int u,int v){
    int f1=top[u],f2=top[v];
    int ans=0;
    while(f1!=f2){
        if(dep[f1]<dep[f2]){
            swap(f1,f2);
            swap(u,v);
        }
        ans=max(ans,query(p[f1],p[u],1,pos-1,1));
        u=fa[f1];f1=top[u];
    }
    if(u==v) return ans;
    if(dep[u]>dep[v]) swap(u,v);
    return max(ans,query(p[son[u]],p[v],1,pos-1,1));
}
int e[maxn][3];
int main()
{
    int T;cin>>T;
    while(T--){
        Init();
        scanf("%d",&n);
        for(int i=0;i<n-1;++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]);
        }
        dfs1(1,0,0);
        getpos(1,1);
        for(int i=0;i<n-1;++i){
            if(dep[e[i][0]]>dep[e[i][1]]) swap(e[i][0],e[i][1]);
            update(p[e[i][1]],e[i][2],1,pos-1,1);
        }
        char op[10];
        int u,v;
        while(scanf("%s",op)==1){
            if(op[0]=='D') break;
            scanf("%d%d",&u,&v);
            if(op[0]=='Q') printf("%d\n",find(u,v));
            else update(p[e[u-1][1]],v,1,pos-1,1);
        }
    }
    return 0;
}

你可能感兴趣的:(Spoj375.Query on a tree——树链剖分+线段树(基于边权))