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

    题目描述:

    luogu

    bz

    题解:

    动态点分治。

    记录点分树子树中到该点的所有价值。

    为啥别人100行我150啊。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 100050;
    template<typename T>
    inline void read(T&x)
    {
        T f = 1,c = 0;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){c=c*10+ch-'0';ch=getchar();}
        x = f*c;
    }
    int n,Q,hed[N],cnt;
    struct EG
    {
        int to,nxt;
        ll w;
    }e[N<<1];
    void ae(int f,int t,ll w)
    {
        e[++cnt].to = t;
        e[cnt].nxt = hed[f];
        e[cnt].w = w;
        hed[f] = cnt;
    }
    int dep[N],siz[N],fa[N],son[N],top[N];
    ll dis[N];
    void dfs0(int u,int f)
    {
        fa[u] = f,siz[u] = 1,dep[u] = dep[f]+1;
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(to==f)continue;
            dis[to] = dis[u]+e[j].w;
            dfs0(to,u);
            siz[u]+=siz[to];
            if(siz[to]>siz[son[u]])son[u]=to;
        }
    }
    void dfs1(int u,int Top)
    {
        top[u] = Top;
        if(son[u])dfs1(son[u],Top);
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(to!=fa[u]&&to!=son[u])
                dfs1(to,to);
        }
    }
    int get_lca(int x,int y)
    {
        while(top[x]!=top[y])
        {
            if(dep[top[x]]<dep[top[y]])swap(x,y);
            x = fa[top[x]];
        }
        return dep[x]<dep[y]?x:y;
    }
    ll get_dis(int x,int y){return dis[x]+dis[y]-2ll*dis[get_lca(x,y)];}
    ll get_dis(int x,int y,int l){return dis[x]+dis[y]-2ll*dis[l];}
    int sum,rt,sz[N],mx[N],ff[N];
    ll k1[N],k2[N],k3[N];
    bool mrk[N];
    void get_rt(int u,int f)
    {
        mx[u] = 0,sz[u] = 1;
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(to==f||mrk[to])continue;
            get_rt(to,u);
            sz[u]+=sz[to];
            mx[u] = max(mx[u],sz[to]);
        }
        mx[u] = max(mx[u],sum-sz[u]);
        if(mx[u]<mx[rt])rt=u;
    }
    void work(int u)
    {
        mrk[u] = 1;int tmp = sum;
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(mrk[to])continue;
            rt=0,sum=(sz[to]>sz[u])?tmp-sz[u]:sz[to];
            get_rt(to,0);ff[rt]=u;work(rt);
        }
    }
    int Rt=1;
    ll ans,ds[N][22];
    void up(int x,ll y)
    {
        for(int i=x,j=0,k=0;i;j=i,i=ff[i],k++)
        {
            ll now = y*ds[x][k];
            k1[i]+=now;k3[i]+=y;
            if(j)k2[j]+=now;
        }
    }
    ll query(int x)
    {
        ll ret = 0;
        for(int i=x,j=0,k=0;i;j=i,i=ff[i],k++)
            ret+=k1[i]-k2[i]+(k3[i]-k3[j])*ds[x][k];
        return ret;
    }
    int turn()
    {
        int son = 0;ll bas = query(Rt);
        for(int j=hed[Rt];j;j=e[j].nxt)
        {
            int to = e[j].to;ll tmp = query(to);
            if(tmp<bas)son=to,bas=tmp;
        }
        if(!son)return 0;
        Rt = son;return 1;
    }
    int main()
    {
    //    freopen("1.in","r",stdin);
        read(n),read(Q);
        for(int u,v,w,i=1;i<n;i++)
        {
            read(u),read(v),read(w);
            ae(u,v,w),ae(v,u,w);
        }
        dfs0(1,0),dfs1(1,1);
        mx[rt=0]=0x3f3f3f3f,sum=n;
        get_rt(1,0);work(rt);
        for(int i=1;i<=n;i++)
            for(int j=1,k=ff[i];k;j++,k=ff[k])
                ds[i][j]=get_dis(i,k);
        int x,y;
        read(x),read(y);
        Rt = x,ans = 0;up(x,y);
        puts("0");
        for(int i=2;i<=Q;i++)
        {
            read(x),read(y);
            up(x,y);
            while(turn());
            printf("%lld
    ",query(Rt));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    常见错误3——错误2 error C2143: 语法错误 : 缺少“;”(在“}”的前面)
    MFC DLL封装窗体详细步骤
    指针函数与函数指针的区别
    DOM
    BOM
    JS动态创建元素
    JS节点
    事件和节点部分总结
    DOM基础
    自定义对象
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/11152868.html
Copyright © 2011-2022 走看看