1. 程式人生 > >【51nod】1149 Pi的遞推式

【51nod】1149 Pi的遞推式

names set air Go putc bitset 組合數 == AS

題解

我們把這個函數的遞歸形式畫成一張圖,會發現答案是到每個出度為0的點的路徑的方案數

這個可以用組合數算

記錄一下P[i]為i減幾次PI減到4以內

如果P[i + 1] > P[i],那麽轉向的路徑走P[i]次,否則走P[i] - 1次

代碼

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#include <bitset>
#define enter putchar(‘\n‘) #define space putchar(‘ ‘) //#define ivorysi #define pb push_back #define mo 974711 #define pii pair<int,int> #define mp make_pair #define fi first #define se second #define MAXN 1000005 using namespace std; typedef long long int64; typedef double db; template<class T> void
read(T &res) { res = 0;char c = getchar();T f = 1; while(c < ‘0‘ || c > ‘9‘) { if(c == ‘-‘) f = -1; c = getchar(); } while(c >= ‘0‘ && c <= ‘9‘) { res = res * 10 - ‘0‘ + c; c = getchar(); } res = res * f; } template<class T> void out(T x) { if
(x < 0) {x = -x;putchar(‘-‘);} if(x >= 10) out(x / 10); putchar(‘0‘ + x % 10); } const int MOD = 1000000007; const db PI = acos(-1.0); int N,fac[MAXN],inv[MAXN],invfac[MAXN],P[MAXN]; int mul(int a,int b) { return 1LL * a * b % MOD; } int inc(int a,int b) { return a + b >= MOD ? a + b - MOD : a + b; } int C(int n,int m) { if(n < m) return 0; return mul(mul(fac[n],invfac[m]),invfac[n - m]); } void Init() { read(N); fac[0] = 1; for(int i = 1 ; i <= N ; ++i) fac[i] = mul(fac[i - 1],i); inv[1] = 1; for(int i = 2 ; i <= N ; ++i) inv[i] = mul(inv[MOD % i],MOD - MOD / i); invfac[0] = 1; for(int i = 1 ; i <= N ; ++i) invfac[i] = mul(invfac[i - 1],inv[i]); } void Solve() { for(int i = 4 ; i <= N ; ++i) { P[i] = floor((i - 4) / PI) + 1; } if(N < 4) {out(1);enter;return;} int ans = 0; for(int i = N ; i >= 3 ; --i) { int s = N - i,t = P[i] - (P[i + 1] <= P[i]); ans = inc(ans,C(s + t,s)); } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Init(); Solve(); }

【51nod】1149 Pi的遞推式