zoukankan      html  css  js  c++  java
  • E. Alternating Tree 树点分治|树形DP

    题意:给你一颗树,然后这颗树有n*n条路径,a->b和b->a算是一条,然后路径的权值是 vi*(-1)^(i+1)  注意是点有权值。

    从上头往下考虑是点分治,从下向上考虑就是树形DP,分成三类路径:1.指定点单点 2.跨过指定点3.没跨过指定点但不是单点

    细节要好好打磨一下,然后还是用long long比较稳 ,1LL*还是有点危险.

    点分治:

    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=2e5+88;
    const int P=1e9+7;
    vector<int>G[N];
    bool vis[N];
    int SQ,SO,Q,O,q[N],o[N],rt,m,nq[N],no[N],sz[N],v[N],mx[N],ans;
    void dfs(int u,int fa,int S){
        sz[u]=mx[u]=1; 
        q[u]=o[u]=no[u]=nq[u]=0;
        for(int i=0;i<(int)G[u].size();++i) {
            int v=G[u][i];
            if(vis[v]||v==fa) continue;
            dfs(v,u,S);
            sz[u]+=sz[v];
            mx[u]=max(mx[u],sz[v]);
        }
        mx[u]=max(mx[u],S-sz[u]);
        if(m>mx[u]) rt=u,m=mx[u];
    }
    void solve(int u,int nv,int f,int fa,int last){
        int t=(nv+f*v[u])%P;
        if(f==-1) o[fa]=(o[fa]+t)%P,O=(O+t)%P,++no[fa],++SO;
        else q[fa]=(q[fa]+t)%P,Q=(Q+t)%P,++nq[fa],++SQ;
        for(int i=0;i<(int)G[u].size();++i) {
            int v=G[u][i];
            if(v==last||vis[v]) continue;
            solve(v,t,-f,fa,u);
        }
    }
    int work(int u,int S){
        m=1e9+7;
        dfs(u,0,S);
        vis[rt]=1;
        Q=O=SQ=SO=0;
        for(int i=0;i<(int)G[rt].size();++i) if(!vis[G[rt][i]]) solve(G[rt][i],v[rt],-1,G[rt][i],rt);
        for(int i=0;i<(int)G[rt].size();++i) if(!vis[G[rt][i]]){
            int t=G[rt][i];
            ans=((ans-1LL*no[t]*(O-o[t])%P)%P-1LL*o[t]*(SO-no[t])%P)%P;
            ans=(ans+1LL*no[t]*(SO-no[t])%P*v[rt]%P)%P;
            ans=((ans+1LL*nq[t]*(Q-q[t])%P)%P+1LL*q[t]*(SQ-nq[t])%P)%P;
            ans=(ans-1LL*nq[t]*(SQ-nq[t])%P*v[rt]%P)%P;
            ans=(ans+(q[t]<<1)%P)%P;
        }
        ans=((ans+v[rt])%P+P)%P; 
        int nt=rt;
        for(int i=0;i<(int)G[nt].size();++i) if(!vis[G[nt][i]]) 
        work(G[nt][i],sz[G[nt][i]]>sz[nt]?S-sz[nt]:sz[G[nt][i]]);
    }
    int main(){
        int n,x,y;
        scanf("%d",&n);
        for(int i=1;i<=n;++i) scanf("%d",v+i);
        for(int i=1;i<n;++i) {
            scanf("%d%d",&x,&y);
            G[x].push_back(y);
            G[y].push_back(x);
        } 
        work(1,n);
        printf("%d
    ",(ans+P)%P);
    }

    树形DP的思路是参考的这里

    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=2e5+88;
    const int P=1e9+7;
    vector<int>G[N];
    long long dp[N][2],num[N][2],ans,v[N];
    void dfs(int u,int fa){
        for(int i=0;i<(int)G[u].size();++i) {
            int vt=G[u][i];
            if(vt==fa) continue;
            dfs(vt,u);
            dp[u][0]=(((dp[u][0]+dp[vt][1])%P-1LL*v[u]*num[vt][1]%P)%P+P)%P;
            dp[u][1]=(((dp[u][1]+dp[vt][0])%P+1LL*v[u]*num[vt][0]%P)%P+P)%P;
            num[u][0]=(num[u][0]+num[vt][1])%P;
            num[u][1]=(num[u][1]+num[vt][0])%P;
        }
        for(int i=0;i<(int)G[u].size();++i) {
            int vt=G[u][i];
            if(vt==fa) continue;
            ans=(ans+2LL*(num[u][1]-num[vt][0])%P*dp[vt][0]%P+1LL*(num[u][1]-num[vt][0])*v[u]%P*num[vt][0]%P)%P;
            ans=(ans+2LL*(num[u][0]-num[vt][1])%P*dp[vt][1]%P-1LL*(num[u][0]-num[vt][1])*v[u]%P*num[vt][1]%P)%P;
        }
        ans=(ans+(dp[u][1]<<1)%P+v[u])%P;
        ++num[u][1];
        num[u][1]%=P;
        dp[u][1]=(dp[u][1]+v[u])%P;
    }
    int main(){
        int n,x,y;
        scanf("%d",&n);
        for(int i=1;i<=n;++i) scanf("%lld",v+i);
        for(int i=1;i<n;++i) {
            scanf("%d%d",&x,&y);
            G[x].push_back(y);
            G[y].push_back(x);
        } 
        dfs(1,0);
        printf("%lld
    ",(ans+P)%P);
    }
  • 相关阅读:
    6. Flask请求和响应
    5. Flask模板
    FW:Software Testing
    What is the difference between modified duration, effective duration and duration?
    How to push master to QA branch in GIT
    FTPS Firewall
    Query performance optimization of Vertica
    (Forward)5 Public Speaking Tips That'll Prepare You for Any Interview
    (转)The remote certificate is invalid according to the validation procedure
    Change
  • 原文地址:https://www.cnblogs.com/mfys/p/8810857.html
Copyright © 2011-2022 走看看