zoukankan      html  css  js  c++  java
  • loj6094 归乡迷途 / CF814E

    Description

    给出 (n) 个点,和每个点的度构造出一张无向图满足以下两条性质:

    1. (1) 到点 (i) 仅有唯一一条最短路
    2. (1) 到点 (i) 的最短路长度大于等于点 (1) 到点 (i-1) 的最短路长度

    求能构成满足条件的无向图的个数?

    Solution

    咕咕咕。

    传送门

    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    const int mod = 1e9 + 7;
    const int _ = 500 + 10;
    int N, d[_];
    ll f[_][_], g[_][_][_];
    ll fac[_], facinv[_];
    
    ll fastPow(ll a, ll b) {
      ll ans = 1;
      for (; b; b >>= 1) {
        if (b & 1) ans = ans * a % mod;
        a = a * a % mod;
      }
      return ans;
    }
    
    void init() {
      fac[0] = facinv[0] = 1;
      for (int i = 1; i <= N; ++i) fac[i] = fac[i - 1] * i % mod;
      facinv[N] = fastPow(fac[N], mod - 2);
      for (int i = N - 1; i >= 1; --i) facinv[i] = facinv[i + 1] * (i + 1) % mod;
    }
    
    inline ll C(ll m, ll n) {
      return fac[m] * facinv[n] % mod * facinv[m - n] % mod;
    }
    inline void Inc(ll &x, ll y) { x += y, x = x >= mod ? x - mod : x; }
    
    int main() {
    #ifndef ONLINE_JUDGE
      freopen("return.in", "r", stdin);
      freopen("return.out", "w", stdout);
    #endif
      scanf("%d", &N);
      for (int i = 1; i <= N; ++i) scanf("%d", &d[i]);
      init();
      g[0][0][0] = 1;
      for (int i = 0; i <= N; ++i) {
        for (int j = 0; j <= N - i; ++j) {
          if (!i && !j) continue;
          if (!i) {
            for (int k = 2; k <= j - 1; ++k)
              Inc(g[0][i][j], g[0][i][j - k - 1] * C(j - 1, k) % mod * fac[k] %
                                  mod * facinv[2] % mod);
          } else {
            if (i >= 2) Inc(g[0][i][j], (i - 1) * g[0][i - 2][j] % mod);
            if (j >= 1) Inc(g[0][i][j], j * g[0][i][j - 1] % mod);
          }
        }
      }
      for (int i = 1; i < N; ++i) {
        for (int p = 0; p < N - i; ++p) {
          for (int k = 0; k <= p; ++k) {
            int j = p - k;
            if (!j && !k) continue;
            if (j > 0) Inc(g[i][j][k], j * g[i - 1][j - 1][k] % mod);
            if (k > 0) Inc(g[i][j][k], k * g[i - 1][j + 1][k - 1] % mod);
          }
        }
      }
      f[d[1] + 1][d[1]] = 1;
      for (int i = d[1] + 2; i <= N; ++i) {
        for (int j = 1; j <= i - d[1] - 1; ++j) {
          int c[2] = {0};
          for (int k = 1; k < i - j; ++k) {
            ++c[d[i - j - k + 1] - 2];
            Inc(f[i][j], f[i - j][k] * g[j][c[0]][c[1]] % mod);
          }
        }
      }
      ll ans = 0;
      int c[2] = {0};
      for (int i = 1; i < N; ++i) {
        ++c[d[N - i + 1] - 2];
        Inc(ans, f[N][i] * g[0][c[0]][c[1]] % mod);
      }
      cout << ans << endl;
      return 0;
    }
    
  • 相关阅读:
    Codeforces 992C(数学)
    Codeforces 990C (思维)
    Codeforces 989C (构造)
    POJ 1511 Invitation Cards(链式前向星,dij,反向建边)
    Codeforces 1335E2 Three Blocks Palindrome (hard version)(暴力)
    POJ 3273 Monthly Expense(二分)
    POJ 2566 Bound Found(尺取前缀和)
    POJ 1321 棋盘问题(dfs)
    HDU 1506 Largest Rectangle in a Histogram(单调栈)
    POJ 2823 Sliding Window(单调队列)
  • 原文地址:https://www.cnblogs.com/newbielyx/p/13131513.html
Copyright © 2011-2022 走看看