zoukankan      html  css  js  c++  java
  • Luogu3345 [ZJOI2015]幻想乡战略游戏

    Luogu3345 [ZJOI2015]幻想乡战略游戏

    题面:良心洛谷

    解析

    动态点分治。假定我们已经确定了补给点,可以通过在点分树上(O(logn))统计答案,修改亦可(O(logn))做到,具体的话就是维护一下当前重心(w)(sum_{v} d_v)(sum_{v} d_vdist(v,w)),在多维护一个父节点信息,容斥即可。现在考虑如何确定补给点?还是在点分树上操作(因为这样能保证复杂度为(O(logn)),我们视度数为常数),每一次选最优的子树向下走即可,若走不动,那么当前点就是答案了。

    代码

    
    // luogu-judger-enable-o2
    #include<cmath>
    #include<cstdio>
    #include<iostream>
    #define N 100005
    #define LL long long
    using namespace std;
    const int nlog=17;
    inline int In(){
        char c=getchar(); int x=0,ft=1;
        for(;c<'0'||c>'9';c=getchar()) if(c=='-') ft=-1;
        for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
        return x*ft;
    }
    inline int max(int a,int b){
        return a>b?a:b;
    }
    int n,m,h[N],e_tot=0;
    struct Edge{ int to,nex,d; }e[N<<1];
    inline void add(int u,int v,int w){
        e[++e_tot]=(Edge){v,h[u],w}; h[u]=e_tot;
    }
    int d[N],p[N<<1][nlog+5],dfn[N],dfs_clock=0;
    void dfs(int u,int pre,int dep){
        d[u]=dep; p[++dfs_clock][0]=u; dfn[u]=dfs_clock;
        for(int i=h[u],v;i;i=e[i].nex){
            v=e[i].to; if(v==pre) continue;
            dfs(v,u,dep+e[i].d); p[++dfs_clock][0]=u;
        }
    }
    int _p[nlog+5];
    inline void get_st(){
        _p[0]=1; for(int i=1;i<=nlog;++i) _p[i]=_p[i-1]*2;
        for(int j=1;j<=nlog;++j)
        for(int i=1;i+_p[j]<=dfs_clock;++i)
        p[i][j]=d[p[i][j-1]]<d[p[i+_p[j-1]][j-1]]
        ?p[i][j-1]:p[i+_p[j-1]][j-1];
    }
    inline int LCA(int x,int y){
        if(dfn[x]>dfn[y]) swap(x,y);
        int k=log(dfn[y]-dfn[x]+1)/log(2);
        return d[p[dfn[x]][k]]<d[p[dfn[y]-_p[k]+1][k]]?
        p[dfn[x]][k]:p[dfn[y]-_p[k]+1][k];
    }
    inline int dist(int x,int y){
        return d[x]+d[y]-2*d[LCA(x,y)];
    }
    int Sz,Sp_root,root,sz[N],f[N]; bool vis[N];
    void get_rt(int u,int pre){
        sz[u]=1; f[u]=0;
        for(int i=h[u],v;i;i=e[i].nex){
            v=e[i].to; if(vis[v]||v==pre) continue;
            get_rt(v,u); sz[u]+=sz[v]; f[u]=max(f[u],sz[v]);
        }
        f[u]=max(f[u],Sz-sz[u]); if(f[u]<f[root]) root=u;
    }
    int fa[N],_g[N][nlog+5];
    void Solve(int u,int pre,int dep){
        vis[u]=1; fa[u]=pre; int Oth_sz=Sz-sz[u];
        for(int i=h[u],v;i;i=e[i].nex){
            v=e[i].to; if(vis[v]) continue;
            Sz=sz[v]>sz[u]?Oth_sz:sz[v]; root=0;
            get_rt(v,u); _g[v][dep]=root;
            Solve(root,u,dep+1);
        }
    }
    int sz_o[N]; LL sum_o[N],sum_f[N];
    inline void Modify(int u,int C){
        sz_o[u]+=C;
        for(int p=fa[u],l_p=u,dis;p!=-1;p=fa[l_p=p]){
            dis=dist(u,p); sz_o[p]+=C;
            sum_o[p]+=1ll*C*dis; sum_f[l_p]+=1ll*C*dis;
        }
    }
    inline LL Query(int u){
        LL ans=0; ans+=sum_o[u];
        for(int p=fa[u],l_p=u,dis,y;p!=-1;p=fa[l_p=p]){
            dis=dist(u,p); ans+=1ll*dis*(sz_o[p]-sz_o[l_p]);
            ans+=sum_o[p]; ans-=sum_f[l_p];
        }
        return ans;
    }
    inline LL get_ans(){
        LL m_ans,S; int u=Sp_root,y;
        for(int d=0;;++d){
            m_ans=Query(u); y=u;
            for(int i=h[u],v;i;i=e[i].nex){
                v=e[i].to; if(!_g[v][d]) continue;
                if(S=Query(v)<m_ans) m_ans=S,y=_g[v][d];
            }
            if(y==u) break; u=y;
        }
        return m_ans;
    }
    int main(){
        n=In(); m=In();
        for(int i=1,u,v,w;i<n;++i){
            u=In(); v=In(); w=In();
            add(u,v,w); add(v,u,w);
        }
        dfs(1,0,0); get_st();
        Sz=f[0]=n; root=0; get_rt(1,-1);
        Sp_root=root; Solve(root,-1,0);
        for(int i=1,u,val;i<=m;++i){
            u=In(); val=In(); Modify(u,val);
            printf("%lld
    ",get_ans());
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    【部分原创】标准C语言的优先级、结合性、求值顺序、未定义行为和非确定行为浅析
    &&、||、?:、,四个运算符的求值顺序
    [转]说说C语言运算符的“优先级”与“结合性”
    初识Nginx,简单配置实现负载均衡(ubuntu + Nginx + tomcat)
    Hadoop伪分布式模式安装
    HBase hbase-site.xml 参数
    HBase单机环境搭建
    Hadoop单机模式安装
    JAVA笔记整理(一),JAVA介绍
    JAVA笔记整理(十),JAVA中的File
  • 原文地址:https://www.cnblogs.com/pkh68/p/10561788.html
Copyright © 2011-2022 走看看