zoukankan      html  css  js  c++  java
  • SPOJ 375 树链剖分

    思路:
    链剖裸题……

    //By SiriusRen
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 22222
    char 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
    ",ans);
                else xx=rec[edge[xx].to],insert(1,n,1);
            }
        }
    }
    
  • 相关阅读:
    网化商城
    ITU R-REC-S 系列建议书分类
    UDLua
    libev简单使用
    Windows 审计日志 安全部分不刷新的解决办法
    sys.version_info
    mitmproxy 安装
    Python3 os.remove() 方法
    Python3 os.rename() 方法
    python3 unittest
  • 原文地址:https://www.cnblogs.com/SiriusRen/p/6532316.html
Copyright © 2011-2022 走看看