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);
    }
  • 相关阅读:
    1024X768大图 (Wallpaper)
    (Mike Lynch)Application of linear weight neural networks to recognition of hand print characters
    瞬间模糊搜索1000万基本句型的语言算法
    单核与双核的竞争 INTEL P4 670对抗820
    FlashFTP工具的自动缓存服务器目录的功能
    LDAP over SSL (LDAPS) Certificate
    Restart the domain controller in Directory Services Restore Mode Remotely
    How do I install Active Directory on my Windows Server 2003 server?
    指针与指针变量(转)
    How to enable LDAP over SSL with a thirdparty certification authority
  • 原文地址:https://www.cnblogs.com/mfys/p/8810857.html
Copyright © 2011-2022 走看看