SPOJ 375 树链剖分

来源:互联网 发布:编程时间和水平成正比 编辑:程序博客网 时间:2024/05/22 06:29

思路:
链剖裸题……

//By SiriusRen#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 22222char ch[11];int n,cases,root,tree[N*4],xx,yy,ans;int tot,first[N],next[N],v[N],w[N];int cnt,top[N],deep[N],size[N],son[N],rec[N],f[N];struct Edge{int from,to,weight;}edge[N];void add(int x,int y,int z){    w[tot]=z,v[tot]=y;    next[tot]=first[x],first[x]=tot++;}void dfs(int x,int fa){    size[x]=1;son[x]=0;    for(int i=first[x];~i;i=next[i]){        if(v[i]==fa)continue;        f[v[i]]=x;        deep[v[i]]=deep[x]+1;        dfs(v[i],x);        size[x]+=size[v[i]];        if(size[v[i]]>size[son[x]])son[x]=v[i];    }}void dfs2(int x,int fa,int tp){    rec[x]=++cnt;top[x]=tp;    if(son[x])dfs2(son[x],x,tp);    for(int i=first[x];~i;i=next[i])        if(v[i]!=son[x]&&v[i]!=fa)dfs2(v[i],x,v[i]);}void insert(int l,int r,int pos){    if(l==r){tree[pos]=yy;return;}    int mid=(l+r)>>1;    if(mid<xx)insert(mid+1,r,pos<<1|1);    else insert(l,mid,pos<<1);    tree[pos]=max(tree[pos<<1],tree[pos<<1|1]);}int query(int l,int r,int pos,int Left,int Right){    if(l>=Left&&r<=Right)return tree[pos];    int mid=(l+r)>>1;    if(mid<Left)return query(mid+1,r,pos<<1|1,Left,Right);    else if(mid>=Right)return query(l,mid,pos<<1,Left,Right);    else return max(query(l,mid,pos<<1,Left,Right),query(mid+1,r,pos<<1|1,Left,Right));}void find(){    int fx=top[xx],fy=top[yy];    while(fx!=fy){        if(deep[fx]<deep[fy])swap(xx,yy),swap(fx,fy);        ans=max(ans,query(1,n,1,rec[fx],rec[xx]));        xx=f[fx];fx=top[xx];    }    if(xx==yy)return;    if(deep[xx]>deep[yy])swap(xx,yy);    ans=max(ans,query(1,n,1,rec[son[xx]],rec[yy]));}int main(){    scanf("%d",&cases);    while(cases--){        memset(tree,0,sizeof(tree));        memset(size,0,sizeof(size));        memset(first,-1,sizeof(first));        scanf("%d",&n);        for(int i=1;i<n;i++){            scanf("%d%d%d",&edge[i].from,&edge[i].to,&edge[i].weight);            add(edge[i].from,edge[i].to,edge[i].weight);            add(edge[i].to,edge[i].from,edge[i].weight);        }        root=(n+1)>>1;        f[root]=deep[root]=cnt=tot=0;        dfs(root,root),dfs2(root,root,root);        for(int i=1;i<n;i++){            if(deep[edge[i].from]>deep[edge[i].to])swap(edge[i].from,edge[i].to);            xx=rec[edge[i].to],yy=edge[i].weight;            insert(1,cnt,1);        }        while(scanf("%s",ch)&&ch[0]!='D'){            scanf("%d%d",&xx,&yy);            if(ch[0]=='Q')ans=0,find(),printf("%d\n",ans);            else xx=rec[edge[xx].to],insert(1,n,1);        }    }}
0 0
原创粉丝点击