bzoj5219 [Lydsy2017地方のチーム10でも測定〕最長パスを

質問の意味:


実践から

ポイントを凝縮後の最初のトーナメントはチェーンであり、\(1 \)の先頭のノードの数を\(SCC \) したがって\(1 \)始点ノード番号は、最も長い鎖である\(1 \)号ノード\(SCC \)サイズ\(1 + \)トポロジカルノード番号のすべての後に\(SCC \)サイズの合計。

セット\(F_iと\)を表し\(I \)明らかに、コンテストナンバー図ポイントを\(F_iと= 2 ^ {\ {N-FRAC *(1-N-)} {2}} \)

セット\(G_iが\)の大きさを表す\(I \)トーナメントのをしている(SCC \)\プログラムの数は以下のとおりです。

\(g_i = f_i- \和\ limits_ {J = 1} ^ {I-1} C_I ^ J * g_j * F_ {IJ} \)

その配列トポロジ列挙最小\(SCC \)および除外約サイズ、。

列挙後\(1 \)番ノードが配置されている(SCC \)\サイズ(1 \)\ノード・トポロジのシーケンス番号の後にすべてのノードの数

\(ans_{i+j}=\sum\limits_{i=1}^n\sum\limits_{j=0}^{n-i}C_{n-1}^{i-1}*C_{n-i}^{j}*g_i*f_j*f_{n-i-j}\)

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2010;
int n;
ll mod;
ll f[maxn],g[maxn],ans[maxn];
ll C[maxn][maxn];
inline void pre_work(int n)
{
    C[0][0]=1;
    for(int i=1;i<=n;i++)
    {
        C[i][0]=1;
        for(int j=1;j<=i;j++)C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
    }
}
inline ll power(ll x,ll k,ll mod)
{
    ll res=1;
    while(k)
    {
        if(k&1)res=res*x%mod;
        x=x*x%mod;k>>=1;
    }
    return res;
}
int main()
{
    scanf("%d%lld",&n,&mod);
    pre_work(n);
    for(int i=0;i<=n;i++)f[i]=power(2,i*(i-1)/2,mod);
    for(int i=1;i<=n;i++)
    {
        g[i]=f[i];
        for(int j=1;j<i;j++)g[i]=((g[i]-C[i][j]*g[j]%mod*f[i-j]%mod)%mod+mod)%mod;
    }
    for(int i=1;i<=n;i++)
        for(int j=0;j<=n-i;j++)
            ans[i+j]=(ans[i+j]+C[n-1][i-1]*C[n-i][j]%mod*g[i]%mod*f[j]%mod*f[n-i-j]%mod)%mod;
    for(int i=1;i<=n;i++)printf("%lld\n",ans[i]);
    return 0;
}

おすすめ

転載: www.cnblogs.com/nofind/p/12069526.html