今天是真的对我说再见
题解:
第一题:打表可以发现他走的路径是沿边缘的,m+1+ C(m+1, m) + C(m+2, m) + C(m+3, m) + …… + C(m+n, m) ( m > n)
而上面那一坨通过杨辉三角的性质可以发现: C(1, m) + C(2, m) + …… + C(m, m) = C(m+1, m+1) = 1;
C(1, m) + C(2, m) + …… + C(m+n, m) = C(m+n+1, m+1);
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> #define ll long long using namespace std; const ll mod = 1e9 + 7; const int M = 1e6 + 20; ll ans; void exgcd(ll a, ll b, ll &x, ll &y){ if(!b){x = 1; y = 0; return ;} ll x0, y0; exgcd(b, a%b, x0, y0); x = y0; y = x0 - (a/b) * y0; } ll ni(ll a){ ll x, y; exgcd(a, mod, x, y); return (x + mod) % mod; } void get2(ll m, ll n){ ll now = 1, nni = 1; ll q = n + m + 1; for(register ll i = m+2; i <= q; i++) now = now * i % mod * ni(i - m - 1) % mod; ans = now; } int main(){ freopen("inverse.in","r",stdin); freopen("inverse.out","w",stdout); ll m, n; scanf("%I64d%I64d", &m, &n); if(m < n)swap(m, n); ans = 0; get2(m, n); printf("%I64d ", (ans + m) % mod); }
以下是std
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cctype> #include <algorithm> #define N_MAX 200000 #define M_MAX 50 #define lld "%I64u" typedef unsigned long long lnt; typedef unsigned unt; typedef bool bnt; const unt P = 1e9 + 7; inline lnt moc(lnt a) { return a < P ? a : a - P; } inline lnt mod(lnt a) { return a < P ? a : a % P; } inline lnt inv(lnt a) { lnt v = 1; while (a > 1) v = mod(v * (P - P / a)), a = P % a; return v; } const lnt v2 = inv(2); struct buf { operator int() { register int c = getchar(), x = 0; for (;!isdigit(c); c = getchar()); for (; isdigit(c); c = getchar()) x = x * 10 - '0' + c; return x; } } fio; int n, m, i, j, k, a[N_MAX + 2], c[M_MAX + 1], p[M_MAX + 1], s[M_MAX + 1]; lnt w, b[N_MAX + 1], f[N_MAX + 1], ans; inline bnt cmp(int x, int y) { return p[x] < p[y]; } int main() { freopen("crystal.in", "r", stdin); freopen("crystal.out", "w", stdout); n = fio, m = fio; for (i = 1; i <= m; ++i) c[i] = i; b[0] = 1; for (i = 1; i <= n; ++i) b[i] = mod(b[i - 1] * v2); for (i = 1; i <= n; ++i) f[i] = mod(f[i - 1] + b[i] * mod(mod(lnt(2 * i + 3) * i + 3) * i + 3)); for (i = 1; i <= n; ++i) ++s[a[i] = fio]; for (i = 1; i <= n; ++i) { p[a[i]] = i; for (j = 1; j <= m && c[j] != a[i]; ++j); while (j > 1 && p[c[j]] < p[c[j - 1]]) std::swap(c[j], c[j - 1]), --j; for (k = 1; k <= m && !p[c[k]]; ++k); w = i < n ? v2 : 1; for (j = 1; j <= m; ++j) if (!p[j]) w = mod(w * moc(1 - b[s[j] - (a[i + 1] == j)] + P)); ans = mod(ans + w * moc(f[i] - f[i - 1] + P)); w = mod(w * v2); for (j = k; j <= m; ++j) { ans = mod(ans + w * moc(f[i - p[c[j - 1]] - 1] - f[i - p[c[j]]] + P)); if (j < m) ans = mod(ans + mod(w * moc(1 - b[s[c[j]] - 1 - (a[i + 1] == c[j])] + P)) * moc(f[i - p[c[j]]] - f[i - p[c[j]] - 1] + P)); w = mod(w * moc(1 - b[s[c[j]] - (a[i + 1] == c[j])] + P)); } } printf(lld " ", mod(ans * inv(b[n]))); return 0; }
以下是std
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <cstdio> #include <cmath> #include <algorithm> #define V_MAX 2 #define C_MAX 3 #define Q_MAX 20 #define N_MAX 100000 #define L_MAX 131072 #define R_MAX 17 typedef unsigned long long lnt; typedef unsigned unt; typedef void vnt; typedef double dec; const unt P = 47; const dec tau = std::acos(dec(-1)) * 2; inline unt mod(unt a) { return a % P; } inline unt moc(unt a) { return a < P ? a : a - P; } inline vnt upd(unt & a, unt b) { a = mod(a + b); } inline vnt upc(unt & a, unt b) { a = moc(a + b); } struct vec { dec x, y; vec operator + (const vec & z) const { return (vec) {x + z.x, y + z.y}; } vec operator - (const vec & z) const { return (vec) {x - z.x, y - z.y}; } vec operator * (const vec & z) const { return (vec) {x * z.x - y * z.y, x * z.y + y * z.x}; } friend vec operator * (unt w, const vec & z) { return (vec) {w * z.x, w * z.y}; } } vec_0, vec_1 = (vec) {1, 0}, w[R_MAX]; int L, R, rev[L_MAX + 1]; inline vnt fft(vec a[]) { int i, j, k, r = R; vec x, u, v; for (i = 1; i < L; ++i) if (i < rev[i]) std::swap(a[i], a[rev[i]]); for (k = 1, --r; k < L; k <<= 1, --r) for (i = 0; i < L; i += k << 1) for (j = 0, x = vec_1; j < k; ++j, x = x * w[r]) u = a[i + j], v = x * a[i + j + k], a[i + j] = u + v, a[i + j + k] = u - v; } int V, d[V_MAX][C_MAX]; unt e[V_MAX][C_MAX], f[V_MAX][V_MAX][N_MAX + 1]; vec a[V_MAX][V_MAX][L_MAX + 1], b[V_MAX][V_MAX][L_MAX + 1], c[V_MAX][V_MAX][L_MAX + 1]; inline vnt sol(int l, int r) { if (r - l == 1) { if (l == 0) for (int x = 0; x < V; ++x) f[x][x][0] = 1; for (int x = 0; x < V; ++x) for (int y = 0; y < V; ++y) upd(f[x][y][l + 1], e[x][2] * f[d[x][2]][y][l]); } else { int m = l + ((r - l) >> 1); sol(l, m); if (l == 0) { for (L = 1, R = 0; L < (m - l) * 2 - 1; L <<= 1, ++R); for (int i = 1; i < L; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (R - 1)); w[0] = (vec) {std::cos(tau / L), std::sin(tau / L)}; for (int i = 0; i < R - 1; ++i) w[i + 1] = w[i] * w[i]; for (int x = 0; x < V; ++x) for (int y = 0; y < V; ++y) { for (int i = 0; i < m; ++i) a[x][y][i].x = f[x][y][i], a[x][y][i].y = 0; for (int i = m; i < L; ++i) a[x][y][i] = vec_0; fft(a[x][y]); } for (int x = 0; x < V; ++x) for (int y = 0; y < V; ++y) for (int z = 0; z < V; ++z) for (int i = 0; i < L; ++i) c[x][z][i] = c[x][z][i] + mod(e[x][0] * e[y][1]) * a[d[x][0]][y][i] * a[d[y][1]][z][i]; } else { for (L = 1, R = 0; L < m - l + r - l - 2; L <<= 1, ++R); for (int i = 1; i < L; ++i) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (R - 1)); w[0] = (vec) {std::cos(tau / L), std::sin(tau / L)}; for (int i = 0; i < R - 1; ++i) w[i + 1] = w[i] * w[i]; for (int x = 0; x < V; ++x) for (int y = 0; y < V; ++y) { for (int i = l; i < m; ++i) a[x][y][i - l].x = f[x][y][i], a[x][y][i - l].y = 0; for (int i = m - l; i < L; ++i) a[x][y][i] = vec_0; fft(a[x][y]); } for (int x = 0; x < V; ++x) for (int y = 0; y < V; ++y) { for (int i = 0; i < r - l - 1; ++i) b[x][y][i].x = f[x][y][i], b[x][y][i].y = 0; for (int i = r - l - 1; i < L; ++i) b[x][y][i] = vec_0; fft(b[x][y]); } for (int x = 0; x < V; ++x) for (int y = 0; y < V; ++y) for (int z = 0; z < V; ++z) for (int i = 0; i < L; ++i) c[x][z][i] = c[x][z][i] + mod(e[x][0] * e[y][1]) * (a[d[x][0]][y][i] * b[d[y][1]][z][i] + b[d[x][0]][y][i] * a[d[y][1]][z][i]); } w[0].y = -w[0].y; for (int i = 0; i < R - 1; ++i) w[i + 1] = w[i] * w[i]; for (int u = 0; u < V; ++u) for (int v = 0; v < V; ++v) { fft(c[u][v]); for (int i = m + 1; i < r + 1; ++i) upd(f[u][v][i], unt(lnt(c[u][v][i - l - 2].x / L + 0.5) % P)); for (int i = 0; i < L; ++i) c[u][v][i] = vec_0; } sol(m, r); } } int Q, N; struct qry { int s, t, n; } q[Q_MAX]; int main() { freopen("bracket.in", "r", stdin); freopen("bracket.out", "w", stdout); scanf("%d", &V); for (int x = 0; x < V; ++x) for (int k = 0; k < C_MAX; ++k) scanf("%d %u", &d[x][k], &e[x][k]), e[x][k] %= P; scanf("%d", &Q); for (int k = 0; k < Q; ++k) scanf("%d %d %d", &q[k].s, &q[k].t, &q[k].n), N = std::max(N, q[k].n); sol(0, N); for (int k = 0; k < Q; ++k) printf("%u ", f[q[k].s][q[k].t][q[k].n]); return 0; }