• [ZJOI2015][bzoj3924] 幻想乡战略游戏 [动态点分治]


    唉:-(动态点分治的思想真是复杂......

    先码住,再做几道题再来填坑

    PS:接下来的Code因为用了倍增lca所以TLE一部分,但是懒得改成RMQ了......

    Code:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define ll long long
    using namespace std;
    inline int read(){
        int re=0,flag=1;char ch=getchar();
        while(ch>'9'||ch<'0'){
            if(ch=='-') flag=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
        return re*flag;
    }
    int n,m,cnt,sum,root,first[100010],fa[100010],siz[100010],son[100010];
    bool vis[100010]={0};
    ll dis1[100010],dis2[100010],tot[100010];
    struct edge{
        int to,next,w;
    }a[200010];
    void add(int u,int v,int w){
        a[++cnt]=(edge){v,first[u],w};first[u]=cnt;
        a[++cnt]=(edge){u,first[v],w};first[v]=cnt;
    }
    inline int _max(int l,int r){return (l>r)?l:r;}
    inline int _min(int l,int r){return (l<r)?l:r;}
    inline void _swap(int &l,int &r){l^=r;r^=l;l^=r;}
    struct Original_Tree{
        int cnt,First[100010],dis[100010],dep[100010];
        int st[100010][20];
        struct Edge{int to,next,w;}A[200010];
        void add(int u,int v,int w){
            A[++cnt]=(Edge){v,First[u],w};First[u]=cnt;
            A[++cnt]=(Edge){u,First[v],w};First[v]=cnt;
        }
        void ddfs(int u,int f){
            st[u][0]=f;int i,v;
            //cout<<"dfs "<<u<<" "<<f<<" "<<dis[u]<<" "<<dep[u]<<"
    ";
            for(i=First[u];~i;i=A[i].next){
                v=A[i].to;
                if(v==f) continue;
                dis[v]=dis[u]+A[i].w;dep[v]=dep[u]+1;
                ddfs(v,u);
            }
        }
        void initst(){
            dis[1]=0;dep[1]=1;ddfs(1,0);int i,j;
            for(j=1;j<20;j++){
                for(i=1;i<=n;i++) st[i][j]=st[st[i][j-1]][j-1];
            }
            //for(i=1;i<=n;i++){
                //for(j=0;j<=3;j++) cout<<st[i][j]<<" ";
                //cout<<"
    ";
            //}
        }
        int getdis(int u,int v){
            if(dep[u]>dep[v]) _swap(u,v);
            int i,lca,tu=u,tv=v;
            //cout<<"begin "<<u<<" "<<v<<"
    ";
            for(i=19;i>=0;i--) 
                if(dep[st[v][i]]>=dep[u]) v=st[v][i];
            //cout<<"half finish "<<u<<" "<<v<<"
    ";
            if(u==v) return dis[tv]-dis[u];
            for(i=19;i>=0;i--)
                if(st[u][i]!=st[v][i]){
                    u=st[u][i];
                    v=st[v][i];
                }
            lca=st[u][0];
            //cout<<"getdis "<<tu<<" "<<tv<<" "<<lca<<"
    ";
            return dis[tu]+dis[tv]-2*dis[lca];
        }
    }T;
    void getroot(int u,int f){
        int i,v;siz[u]=1;son[u]=0;
        for(i=T.First[u];~i;i=T.A[i].next){
            v=T.A[i].to;
            if(v==f||vis[v]) continue;
            getroot(v,u);
            siz[u]+=siz[v];son[u]=_max(son[u],siz[v]);
        }
        son[u]=_max(son[u],sum-siz[u]);
        if(son[u]<son[root]) root=u;
    }
    void dfs(int u,int f){
        int i,v;vis[u]=1;fa[u]=f;
        for(i=T.First[u];~i;i=T.A[i].next){
            v=T.A[i].to;
            if(vis[v]) continue;
            sum=siz[v];root=0;
            getroot(v,0);add(u,root,v);
            dfs(root,u);
        }
    }
    void change(int u,int delta){
        tot[u]+=delta;int v,dis;
        for(v=u;fa[v];v=fa[v]){
            dis=T.getdis(u,fa[v]);
            dis1[fa[v]]+=(ll)dis*delta;
            dis2[v]+=(ll)dis*delta;
            tot[fa[v]]+=delta;
        }
    }
    ll calc(int u){
        ll re=dis1[u];int i,dis;
        for(i=u;fa[i];i=fa[i]){
            dis=T.getdis(u,fa[i]);
            re+=dis1[fa[i]]-dis2[i];
            re+=dis*(tot[fa[i]]-tot[i]);
        }
        return re;
    }
    ll query(int u){
        ll re=calc(u),tmp;int i,v;
        for(i=first[u];~i;i=a[i].next){
            v=a[i].to;
            tmp=calc(a[i].w);
            if(tmp<re) return query(v);
        }
        return re;
    }
    int main(){
        freopen("zjoi15_tree4.in","r",stdin);
        freopen("zjoi15_tree.out","w",stdout);
    
        memset(tot,0,sizeof(tot));
        memset(dis1,0,sizeof(dis1));
        memset(dis2,0,sizeof(dis2));
        memset(first,-1,sizeof(first));
        memset(T.First,-1,sizeof(T.First));
        int i,t1,t2,t3,tmp;
        n=read();m=read();
        for(i=1;i<n;i++){
            t1=read();t2=read();t3=read();
            T.add(t1,t2,t3);
        }
        T.initst();
        sum=son[0]=n;root=0;
        getroot(1,0);tmp=root;
        dfs(root,0);root=tmp;
        for(i=1;i<=m;i++){
            t1=read();t2=read();
            change(t1,t2);
            printf("%lld
    ",query(root));
        }
    }
  • 相关阅读:
    在线加密解密
    ctcms Nginx 伪静态
    iTem2 保持连接,解决ssh的"Write failed: Broken pipe"问题
    打开窗口弹出页面
    点击弹窗
    javascript 技巧
    使用Chrome工具来分析页面的绘制状态
    jquery结合JSONP教程—明河谈jquery
    使用 JSONP 实现跨域通信,第 1 部分: 结合 JSONP 和 jQuery 快速构建强大的 mashup
    jsonp详解
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8425978.html
Copyright © 2020-2023  润新知