zoukankan      html  css  js  c++  java
  • Codeforces 543D Road Improvement

    http://codeforces.com/contest/543/problem/D

    题意:

    给定n个点的树

    问:

    一开始全是黑边,对于以i为根时,把树边白染色,使得任意点走到根的路径上不超过一条黑边,输出染色的方案数(mod 1e9+7)

    思路:得知f[x]=(f[s1]+1)*(f[s2]+1)*(f[s3]+1)..*(f[sn]+1),s为x的儿子

    因为要么这条边修了,里面有f[s1]方案,要吗不修,那剩下的都必须修。

    由于要计算每个点的答案。

    我们令up[x]为x父亲为x儿子时的f答案。可知up[x]=(fa的f前缀*fa的f后缀*up[fa])+1

    最后f[x]*up[x]就是答案。

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<vector>
    #define ll long long
    const ll Mod=1000000007;
    int tot,go[400005],first[400005],next[400005],n;
    ll up[400005];
    ll f[400005];
    std::vector<int>G[200005];
    std::vector<ll>L[200005],R[200005];
    int read(){
        int t=0,f=1;char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
        while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
        return t*f;
    }
    void dfs1(int x,int fa){
        f[x]=1;
        for (int i=0;i<G[x].size();i++){
            int pur=G[x][i];
            if (pur==fa){
                L[x].push_back(1);
                R[x].push_back(1);
                continue;
            }
            dfs1(pur,x);
            f[x]=(f[x]*(f[pur]+1))%Mod;
            L[x].push_back(f[pur]+1);
            R[x].push_back(f[pur]+1);
        }
        for (int i=1;i<L[x].size();i++)
         L[x][i]=(L[x][i]*L[x][i-1])%Mod;
        for (int i=R[x].size()-2;i>=0;i--)
         R[x][i]=(R[x][i]*R[x][i+1])%Mod; 
    }
    void dfs2(int x,int fa,ll val){
        up[x]=val;
        ll tmp;
        for (int i=0;i<G[x].size();i++){
            int pur=G[x][i];
            if (pur==fa) continue;
            tmp=val;
            if (i>0) tmp=(tmp*L[x][i-1])%Mod;
            if (i<G[x].size()-1) tmp=(tmp*R[x][i+1])%Mod;
            dfs2(pur,x,tmp+1);
        }
    }
    void solve(){
        dfs1(1,0);
        up[1]=1;
        dfs2(1,0,1LL);    
        for (int i=1;i<=n;i++)
         printf("%I64d ",f[i]*up[i]%Mod);
    }
    int main(){
        n=read();for (int i=2;i<=n;i++){int x=read();G[x].push_back(i);G[i].push_back(x);}
        solve();
    }
  • 相关阅读:
    一些无意间YY的脑瘫题
    回滚莫队
    数论
    专题整理
    模拟赛x+1
    HISKrrr的板子库
    java多线程学习笔记(四)
    java多线程学习笔记(三)
    java多线程学习笔记(二)
    Java多线程学习笔记(一)
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5668273.html
Copyright © 2011-2022 走看看