zoukankan      html  css  js  c++  java
  • 2018 icpc Regional Dhaka G Techland

    G techland

    题意:给你一颗树,查询连续的一段节点距离某一个节点的最小距离。

    题解:考虑树上分块。将连续的节点分成sqrt(n)个块,并且在这些块中,采用树形dp,预处理出距离到每一个节点的最小距离。对于块内的部分O(1)的查询。其他的部分,采用树上dfs序,O(1)查询LCA,暴力搞。(码量稍大)

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define fi first
    #define se second
    #define MP make_pair
    
    typedef pair<int,int> PII;
    
    const int N = 100005;
    
    const int M = 21;
    
    const int bSize = 300;
    
    const int INF = 0x3f3f3f3f;
    
    int head[N], Next[N<<1], to[N<<1], tol;
    
    int n, q, fa[N], dep[N], belong[N], bL[N], bR[N];
    
    PII seg[N];
    
    void addAdge(int u, int v){
        Next[++tol]=head[u];to[tol]=v;head[u]=tol;
        Next[++tol]=head[v];to[tol]=u;head[v]=tol;
    }
    
    inline void chmin(int& x, int y){
        if(y<x)x=y;
    }
    
    struct LCA{
        int L[N<<1], dfn, id[N<<1];
    
        struct RMQ{
            int stTable[N<<1][M];
            int lg2[N<<1], depth[N<<1];
    
            void init(int x){
                for(int i=2;i<=x;++i)lg2[i]=lg2[i>>1]+1;
                for(int i=1;i<=x;++i){
                    stTable[i][0]=i;
                }
    
                for(int i=1;i<=20;++i){
                    for(int j=1;j+(1<<i)<=x;++j){
                        stTable[j][i]=depth[stTable[j][i-1]]<depth[stTable[j+(1<<i-1)][i-1]]?stTable[j][i-1]:stTable[j+(1<<i-1)][i-1];
                    }
                }
            }
    
            int query(int x, int y){
                if(x>y)swap(x,y);
                int len=lg2[y-x+1];
                return depth[stTable[x][len]]<depth[stTable[y-(1<<len)+1][len]]?stTable[x][len]:stTable[y-(1<<len)+1][len];
            }
    
        }st;
    
        void dfs(int u){
            //cout<<"n: "<<n<<" "<<u<<endl;
            L[++dfn]=u;
            id[u]=dfn;
            st.depth[dfn]=dep[u];
            for(int e=head[u];e;e=Next[e]){
                int v=to[e];
                if(v==fa[u])continue;
                fa[v]=u;
                dep[v]=dep[u]+1;
                dfs(v);
                L[++dfn]=u;
                st.depth[dfn]=dep[u];
            }
        }
    
        void init(){
            dfn=0;
            fa[1]=1;
            dep[1]=0;
            dfs(1);
            st.init(2*n-1);
        }
    
        inline int query(int u, int v){
            return L[st.query(id[u],id[v])];
        }
    
        inline int dis(int u, int v){
            return dep[u]+dep[v]-2*dep[query(u,v)];
        }
    }qry;
    
    struct bQuery{
        int f[N];
    
        void init(){
            for(int i=1;i<=n;++i){
                f[i]=INF+INF;
            }
        }
    
        void dfs(int u){
            for(int e=head[u];e;e=Next[e]){
                int v=to[e];
                if(v==fa[u])continue;
                dfs(v);
                chmin(f[u],f[v]);
            }
        }
    
        void dfs1(int u){
            f[u]-=2*dep[u];
            chmin(f[u],f[fa[u]]);
            for(int e=head[u];e;e=Next[e]){
                int v=to[e];
                if(v==fa[u])continue;
                dfs1(v);
            }
        }
    
        void get(int x){
            chmin(f[x],dep[x]);
        }
    
        void solve(){
            dfs(1);
            dfs1(1);
        }
    }bInfo[205];
    
    void clr(){
        memset(head,0,sizeof head);
        tol=0;
        memset(seg,-1,sizeof seg);
    }
    
    int bruteForce(int nd, int l, int r){
        int res=INF;
        for(int i=l;i<=r;++i){
            chmin(res,qry.dis(nd,i));
        }
        return res;
    }
    
    int getAns(int nd, int p){
        if(seg[p].fi==-1)return INF;
    
        int res=INF;
        if(belong[seg[p].fi]==belong[seg[p].se]){
            chmin(res,bruteForce(nd,seg[p].fi,seg[p].se));
        }else{
            int l=seg[p].fi, r=seg[p].se;
            chmin(res,bruteForce(nd,l,bR[belong[l]]));
            for(int i=belong[l]+1;i<belong[r];++i){
                chmin(res,bInfo[i].f[nd]+dep[nd]);
            }
            chmin(res,bruteForce(nd,bL[belong[r]],r));
        }
    
        return res;
    }
    
    int main(){
        ios_base::sync_with_stdio(0);
        cin.tie(0);
    
        for(int i=1;i<=100000;++i){
            belong[i]=(i-1)/bSize+1;
            if(i==1||belong[i]!=belong[i-1])bL[belong[i]]=i;
            bR[belong[i]]=i;
        }
    
        int _;cin>>_;
    
        int kase=1;
    
        while(_--){
            clr();
    
            cin>>n;
            for(int i=1;i<n;++i){
                int u, v;
                cin>>u>>v;
                addAdge(u,v);
            }
    
            qry.init();
    
            for(int i=1;i<=belong[n];++i)bInfo[i].init();
    
            for(int i=1;i<=n;++i){
                bInfo[belong[i]].get(i);
            }
    
            for(int i=1;i<=belong[n];++i){
                bInfo[i].solve();
            }
    
            cin>>q;
    
            int op, l, r, x, m, p;
    
            cout<<"Case "<<kase++<<":"<<endl;
    
            while(q--){
                cin>>op;
                if(op==1){
                    cin>>x>>l>>r;
                    seg[x]=MP(l,r);
                }else if(op==2){
                    cin>>x;
                    seg[x]=MP(-1,-1);
                }else{
                    int res=INF;
                    cin>>x>>m;
                    for(int i=1;i<=m;++i){
                        cin>>p;
                        chmin(res,getAns(x,p));
                    }
                    if(res>=INF)res=-1;
                    cout<<res<<endl;
                }
            }
        }
    
        return 0;
    }
    
    
  • 相关阅读:
    FEniCS 1.1.0 发布,计算算术模型
    Piwik 1.10 发布,增加社交网站统计
    淘宝褚霸谈做技术的心态
    CyanogenMod 10.1 M1 发布
    Druid 发布 0.2.11 版本,数据库连接池
    GNU Gatekeeper 3.2 发布
    Phalcon 0.9.0 BETA版本发布,新增大量功能
    EUGene 2.6.1 发布,UML 模型操作工具
    CVSps 3.10 发布,CVS 资料库更改收集
    Opera 移动版将采用 WebKit 引擎
  • 原文地址:https://www.cnblogs.com/JohnRan/p/13845222.html
Copyright © 2011-2022 走看看