【树链剖分】[SPOJ-QTREE]Query on a tree

题目
模板题,存代码。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace  std;
#define MAXN 10024
#define MAXLOG 14
#define INF 0x7fffffff
int n,T,size[MAXN+10],dep[MAXN+10],fa[MAXN+10][MAXLOG+1],wt[MAXN+10]={0,-INF},bl[MAXN+10],length[MAXN+10],id2v[MAXN+10];
int tmax[MAXN*4+10],*ttop,*root[MAXN+10],pos[MAXN+10];
bool f;
struct node{
    int v,wt,pos;
    node *next;
}*adj[MAXN+10],edge[MAXN*2+10],*ecnt;
void addedge(int u,int v,int wt,int pos){
    node *p=++ecnt;
    p->v=v;
    p->wt=wt;
    p->pos=pos;
    p->next=adj[u];
    adj[u]=p;
}
void Read(int &x){
    char c;
    while(c=getchar(),c!=EOF)
        if(c>='0'&&c<='9'){
            x=c-'0';
            while(c=getchar(),c>='0'&&c<='9')
                x=x*10+c-'0';
            ungetc(c,stdin);
            return;
        }
}
void dfs1(int u,int father){
    fa[u][0]=father;
    dep[u]=dep[father]+1;
    size[u]=1;
    for(int i=1;i<=MAXLOG;i++)
        fa[u][i]=fa[fa[u][i-1]][i-1];
    for(node *p=adj[u];p;p=p->next){
        if(p->v!=father){
            id2v[p->pos]=p->v;
            wt[p->v]=p->wt;
            dfs1(p->v,u);
            size[u]+=size[p->v];
        }
    }
}
inline int *NewTree(int len){
    int *ret=ttop;
    ttop+=len*4;
    return ret;
}
void insert(int *tmax,int i,int l,int r,int pos,int wt){
    if(l==r){
        tmax[i]=wt;
        return;
    }
    int mid=(l+r)>>1;
    if(pos<=mid)
        insert(tmax,i<<1,l,mid,pos,wt);
    else
        insert(tmax,(i<<1)+1,mid+1,r,pos,wt);
    tmax[i]=max(tmax[i<<1],tmax[(i<<1)+1]);
}
void dfs2(int u,int len,int father){
    int heavy=0,i;
    for(node *p=adj[u];p;p=p->next)
        if(p->v!=father&&size[p->v]>size[heavy])
            heavy=p->v;
    if(!heavy){
        int tp=u;
        for(i=1;i<len;i++)
            tp=fa[tp][0];
        root[tp]=NewTree(len);
        length[tp]=len;
        for(i=len;i;i--){
            bl[u]=tp;
            pos[u]=i;
            insert(root[tp],1,1,len,i,wt[u]);
            u=fa[u][0];
        }
        return;
    }
    dfs2(heavy,len+1,u);
    for(node *p=adj[u];p;p=p->next){
        if(p->v!=father&&p->v!=heavy)
            dfs2(p->v,1,u);
    }
}
void init(){
    Read(n);
    int i,u,v,wt;
    for(i=1;i<n;i++){
        Read(u),Read(v),Read(wt);
        addedge(u,v,wt,i);
        addedge(v,u,wt,i);
    }
    dfs1(1,0);
    dfs2(1,1,0);
}
int LCA(int a,int b){
    if(dep[a]<dep[b])
        swap(a,b);
    int i;
    for(i=MAXLOG;i>=0;i--)
        if(dep[a]-(1<<i)>=dep[b])
            a=fa[a][i];
    if(a==b)
        return a;
    for(i=MAXLOG;i>=0;i--)
        if(fa[a][i]&&fa[a][i]!=fa[b][i])
            a=fa[a][i],b=fa[b][i];
    return fa[a][0];
}
int find(int *tmax,int i,int l,int r,int ll,int rr){
    if(l>=ll&&r<=rr)
        return tmax[i];
    if(l>rr||r<ll)
        return -INF;
    int mid=(l+r)>>1;
    return max(find(tmax,i<<1,l,mid,ll,rr),find(tmax,(i<<1)+1,mid+1,r,ll,rr));
}
int query(int lca,int a){
    int ret=-INF;
    while(lca!=a){
        if(bl[a]!=bl[lca]){
            ret=max(find(root[bl[a]],1,1,length[bl[a]],1,pos[a]),ret);
            a=fa[bl[a]][0];
        }
        else{
            ret=max(find(root[bl[a]],1,1,length[bl[a]],pos[lca]+1,pos[a]),ret);
            break;
        }
    }
    return ret;
}
void solve(){
    char s[10];
    int lca,a,b;
    while(scanf("%s",s),s[0]!='D'){
        Read(a),Read(b);
        if(s[0]=='Q'){
            lca=LCA(a,b);
            printf("%d\n",max(query(lca,a),query(lca,b)));
        }
        else{
            wt[id2v[a]]=b;
            insert(root[bl[id2v[a]]],1,1,length[bl[id2v[a]]],pos[id2v[a]],b);
        }
    }
}
int main()
{
    Read(T);
    while(T--){
        memset(fa,0,sizeof fa);
        memset(adj,0,sizeof adj);
        memset(tmax,0,sizeof tmax);
        ttop=tmax;
        ecnt=edge;
        init();
        solve();
    }
}
posted @ 2015-11-15 20:54  outer_form  阅读(172)  评论(0编辑  收藏  举报