Challenge: Strongly Connected Digraphs

Subdomeniu: Combinatorics (combinatorics)

Scor cont: 120.0 / 120

Submission status: Accepted

Submission score: 1.0

Submission ID: 464815861

Limbaj: cpp14

Link challenge: https://www.hackerrank.com/challenges/strongly-connected-digraphs/problem

Cerinta

Count the number of [labeled strongly connected digraphs](http://en.wikipedia.org/wiki/Directed_graph) with the given number of vertices.  

**Input Format**  
The first line contains $T$, the number of queries.  
Following are $T$ lines. Each line contains one integer $N$, denoting the number of vertices.  

**Output Format**  
Output $T$ lines. Each line is the number of labeled strongly connected digraphs with $N$ vertices, modulo $(10^9 + 7)$. 

**Constraints**  
$1 \le T \le 1000$  
$1 \le N \le 1000$  

**Sample Input**

	5
	1
	2
	3
	4
	1000

**Sample Output**

	1
	1
    18
    1606
    871606913

**Explanation**

You can refer to [oeis](http://oeis.org/A003030).

Cod sursa

#include <bits/stdc++.h>
using namespace std;

static const int MOD = 1000000007;

static inline int addm(int a, int b) {
    a += b;
    if (a >= MOD) a -= MOD;
    return a;
}
static inline int subm(int a, int b) {
    a -= b;
    if (a < 0) a += MOD;
    return a;
}
static inline int mulm(long long a, long long b) {
    return (int)((a * b) % MOD);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int T;
    cin >> T;
    vector<int> q(T);
    int Nmax = 0;
    for (int i = 0; i < T; ++i) {
        cin >> q[i];
        Nmax = max(Nmax, q[i]);
    }

    int maxPow = Nmax * (Nmax - 1);
    vector<int> pow2(maxPow + 1, 1);
    for (int i = 1; i <= maxPow; ++i) pow2[i] = addm(pow2[i - 1], pow2[i - 1]);

    vector<vector<int>> C(Nmax + 1, vector<int>(Nmax + 1, 0));
    for (int n = 0; n <= Nmax; ++n) {
        C[n][0] = C[n][n] = 1;
        for (int k = 1; k < n; ++k) C[n][k] = addm(C[n - 1][k - 1], C[n - 1][k]);
    }

    vector<int> b(Nmax + 1, 0), a(Nmax + 1, 0);
    if (Nmax >= 1) {
        b[1] = 1;
        a[1] = 1;
    }

    for (int n = 2; n <= Nmax; ++n) {
        int val = pow2[n * (n - 1)];
        for (int j = 1; j <= n - 1; ++j) {
            int term = mulm(C[n][j], mulm(pow2[(n - 1) * (n - j)], b[j]));
            val = subm(val, term);
        }
        b[n] = val;
    }

    for (int n = 2; n <= Nmax; ++n) {
        int val = b[n];
        for (int j = 1; j <= n - 1; ++j) {
            int term = mulm(C[n - 1][j - 1], mulm(b[n - j], a[j]));
            val = addm(val, term);
        }
        a[n] = val;
    }

    for (int n : q) {
        cout << a[n] << '\n';
    }

    return 0;
}
HackerRank Combinatorics – Strongly Connected Digraphs