• 2016MUTC9 HDU5852 Intersection is not allowed!


    题目大意

    给定一个$n imes n$的棋盘,从求从最上一行的$k$个点出发,每次只能往下或往左走不相交地走到最下面一行$k$个点的方案数。

    简要题解

    建立一个$k imes k$的矩阵$D$,其中$D_{ij}$表示从$a_i$到$b_j$的方案数,由Lindström–Gessel–Viennot lemma,答案即为$Det(D)$。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 namespace my_header {
      4 #define pb push_back
      5 #define mp make_pair
      6 #define pir pair<int, int>
      7 #define vec vector<int>
      8 #define pc putchar
      9 #define clr(t) memset(t, 0, sizeof t)
     10 #define pse(t, v) memset(t, v, sizeof t)
     11 #define bl puts("")
     12 #define wn(x) wr(x), bl
     13 #define ws(x) wr(x), pc(' ')
     14     const int INF = 0x3f3f3f3f;
     15     typedef long long LL;
     16     typedef double DB;
     17     inline char gchar() {
     18         char ret = getchar();
     19         for(; (ret == '
    ' || ret == '
    ' || ret == ' ') && ret != EOF; ret = getchar());
     20         return ret; }
     21     template<class T> inline void fr(T &ret, char c = ' ', int flg = 1) {
     22         for(c = getchar(); (c < '0' || '9' < c) && c != '-'; c = getchar());
     23         if (c == '-') { flg = -1; c = getchar(); }
     24         for(ret = 0; '0' <= c && c <= '9'; c = getchar())
     25             ret = ret * 10 + c - '0';
     26         ret = ret * flg; }
     27     inline int fr() { int t; fr(t); return t; }
     28     template<class T> inline void fr(T&a, T&b) { fr(a), fr(b); }
     29     template<class T> inline void fr(T&a, T&b, T&c) { fr(a), fr(b), fr(c); }
     30     template<class T> inline char wr(T a, int b = 10, bool p = 1) {
     31         return a < 0 ? pc('-'), wr(-a, b, 0) : (a == 0 ? (p ? pc('0') : p) : 
     32             (wr(a/b, b, 0), pc('0' + a % b)));
     33     }
     34     template<class T> inline void wt(T a) { wn(a); }
     35     template<class T> inline void wt(T a, T b) { ws(a), wn(b); }
     36     template<class T> inline void wt(T a, T b, T c) { ws(a), ws(b), wn(c); }
     37     template<class T> inline void wt(T a, T b, T c, T d) { ws(a), ws(b), ws(c), wn(d); }
     38     template<class T> inline T gcd(T a, T b) {
     39         return b == 0 ? a : gcd(b, a % b); }
     40     template<class T> inline T fpw(T b, T i, T _m, T r = 1) {
     41         for(; i; i >>= 1, b = b * b % _m)
     42             if(i & 1) r = r * b % _m;
     43         return r; }
     44 };
     45 using namespace my_header;
     46 
     47 const int MOD = 1e9 + 7;
     48 const int MAXN = 2e5 + 100;
     49 const int MAXK = 100 + 10;
     50 
     51 int fac[MAXN], rfac[MAXN], rev[MAXN];
     52 
     53 void init() {
     54     fac[0] = 1;
     55     for (int i = 1; i < MAXN; ++i)
     56         fac[i] = 1LL * fac[i - 1] * i % MOD;
     57     rfac[MAXN - 1] = fpw((LL)fac[MAXN - 1], (LL)MOD - 2, (LL)MOD);
     58     for (int i = MAXN - 2; 0 <= i; --i)
     59         rfac[i] = 1LL * rfac[i + 1] * (i + 1) % MOD;
     60     for (int i = 1; i < MAXN; ++i)
     61         rev[i] = 1LL * fac[i - 1] * rfac[i] % MOD;
     62 }
     63 
     64 int c(int n, int m) {
     65     if (n < m)
     66         return 0;
     67     return 1LL * fac[n] * rfac[m] % MOD * rfac[n - m] % MOD;
     68 }
     69 
     70 int det(int (*d)[MAXK], int n) {
     71     int ans = 1, s = 1;
     72     for (int i = 1; i <= n; ++i) {
     73         for (int j = i + 1; j <= n; ++j) {
     74             int x = i, y = j;
     75             while (d[y][i]) {
     76                 int t = d[x][i] / d[y][i];
     77                 for (int k = i; k <= n; ++k)
     78                     d[x][k] = (d[x][k] - 1LL * d[y][k]* t % MOD + MOD) % MOD;
     79                 swap(x, y);
     80             }
     81             if (x != i) {
     82                 for (int k = i; k <= n; ++k)
     83                     swap(d[x][k], d[y][k]);
     84                 s *= -1;
     85             }
     86         }
     87         if (d[i][i] == 0)
     88             return 0;
     89         ans = 1LL * ans * d[i][i] % MOD;
     90     }
     91     return (ans * s % MOD + MOD) % MOD;
     92 }
     93 
     94 int n, k, a[MAXK], b[MAXK], d[MAXK][MAXK];
     95 
     96 int getNum(int u, int v) {
     97     return c(n + v - u - 1, n - 1);
     98 }
     99 
    100 int main() {
    101 #ifdef lol
    102     freopen("h.in", "r", stdin);
    103     freopen("h.out", "w", stdout);
    104 #endif
    105     init();
    106     int T = fr();
    107     while (T--) {
    108         fr(n, k);
    109         for (int i = 1; i <= k; ++i)
    110             fr(a[i]);
    111         for (int i = 1; i <= k; ++i)
    112             fr(b[i]);
    113         for (int i = 1; i <= k; ++i)
    114             for (int j = 1; j <= k; ++j)
    115                 d[i][j] = getNum(a[i], b[j]);
    116         wt(det(d, k));
    117     }
    118 
    119     return 0;
    120 }
  • 相关阅读:
    http://www.jdon.com/jivejdon/thread/37340
    我的英语死在类似的问题上
    Linux之read命令使用
    SIP注册呼叫流程简介
    sh里的变量 $0 $1 $$ $#
    LTE 逻辑分层和接口协议
    LTE语音业务VOLTE
    shell编程——if语句 if z n f eq ne lt
    高通QXDM抓modem log
    LTE与VOLTE基础知识
  • 原文地址:https://www.cnblogs.com/ichn/p/6410178.html
Copyright © 2020-2023  润新知