Frightful Formula

做了幾天勝選模擬就做出來一道題【完 全 自 閉

題意

已知 fi,1=li,f1,i=ti,fi,j=afi,j1+bfi1,j+cf_{i,1}=l_i,f_{1,i}=t_i,f_{i,j}=af_{i,j-1}+bf_{i-1,j}+c ,求 fn,nmod  1000003f_{n,n} \mod 1000003

思路

我們需要將 li,ti,cl_i,t_i,c 分開處理。

  1. 首先,我們先來康康 c=0c=0 的情況。
    我們只需要計算 li,til_i,t_i 的貢獻。對於第一列的 lil_i,它每往下一步(i++i++),貢獻就乘以 aa,每往右一步(j++j++),貢獻就乘以 bb,並且從 (i,1)(i,1) 到達 (n,n)(n,n) 總共向下 nin-i 步,向右 n1n-1 步,有 (2ni2n2)\binom{2n-i-2}{n-2} 種方案(第一步只能往右),於是貢獻就是 anibn1(2ni2n2)a^{n-i}b^{n-1}\binom{2n-i-2}{n-2}
  2. 然後,我們來計算 cc 的貢獻。
    (i,j)(i>1,j>1)(i,j)(i>1,j>1) 出發,貢獻爲 anibmj(ni+mjni)a^{n-i}b^{m-j}\binom{n-i+m-j}{n-i}

第1步的貢獻只要 O(N)O(N) 就可以算出來了。
第2步的貢獻的答案就是
i=0n2j=0n2aibj(i+ji)=i=0n2aii!j=0n2bjj!(i+j)! \sum_{i=0}^{n-2}\sum_{j=0}^{n-2}a^ib^j\binom{i+j}{i}=\sum_{i=0}^{n-2}\frac{a^i}{i!}\sum_{j=0}^{n-2}\frac{b_j}{j!}(i+j)!
多麼優美的卷積。
呸呸呸寫個*的多項式!!!
我們來看看有什麼奇技淫巧。
ca0b0(0+00)ca1b0(1+01)ca2b0(2+02)ca0b1(0+10)ca1b1(1+11)ca2b1(2+12)ca0b2(0+20)ca1b2(1+21)ca2b2(2+22) \begin{matrix} ca^0b^0\binom{0+0}{0} & ca^1b^0\binom{1+0}{1} & ca^2b^0\binom{2+0}{2} \\ ca^0b^1\binom{0+1}{0} & ca^1b^1\binom{1+1}{1} & ca^2b^1\binom{2+1}{2} \\ ca^0b^2\binom{0+2}{0} & ca^1b^2\binom{1+2}{1} & ca^2b^2\binom{2+2}{2} \\ \end{matrix}
對於 i+jn2,(i,j[0,n2])i+j\le n-2,(i,j\in[0,n-2]),我們發現貢獻之和就是 i=0n2(a+b)i\sum_{i=0}^{n-2} (a+b)^i
對於剩下的貢獻,我們從 i+j=n2i+j=n-2 的所有貢獻 ss 乘上 (a+b)(a+b),再減去 ca0b2(0+20)×b+ca2b0(2+00)×aca^0b^2\binom{0+2}{0}\times b+ca^2b^0\binom{2+0}{0}\times a,就是 i+j=n1i+j=n-1 的貢獻啦QAQ,然後這麼幹幾次就是所有貢獻了。
是不是比**的卷積好些多了呀!

代碼

#include<bits/stdc++.h>
using namespace std;
#define open(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout)
#define i64 long long
#define rgt register
#define fp( i, b, e ) for ( rgt int i(b), I(e); i <= I; ++i )
#define fd( i, b, e ) for ( rgt int i(b), I(e); i >= I; --i )
#define go( i, b ) for ( int i(b), v(to[i]); i; v = to[i = nxt[i]] )
template<typename T> inline bool cmax( T &x, T y ){ return x < y ? x = y, 1 : 0; }
template<typename T> inline bool cmin( T &x, T y ){ return y < x ? x = y, 1 : 0; }

const int _ = 2e5 + 55, mod = 1e6 + 3;
int N, M, a, b, c;
int l[_], t[_], pa[_], pb[_];
int fac[_<<1], inv[_<<1];

inline int Pow( int x, int y = mod - 2 ){ int ans(1); for ( ; y; y >>= 1, x = (i64)x * x % mod ) if ( y & 1 ) ans = (i64)ans * x % mod; return ans; }
inline int C( int n, int m ){ return (i64)fac[n] * inv[m] * inv[n - m] % mod; }
inline int calc( int n, int m ){ return (i64)fac[n + m - 2] * inv[n - 1] % mod * inv[m - 1] % mod; }
inline int dec( int x ){ return x >= mod ? x - mod : x; }

namespace brute{
	int f[1005][1005];
	void solve(){
		fp( i, 1, N ) f[i][1] = l[i], f[1][i] = t[i];
		fp( i, 2, N ) fp( j, 2, N )
			f[i][j] = ((i64)a * f[i][j - 1] + (i64)b * f[i - 1][j] + c) % mod;
		printf( "%d\n", f[N][N] );
	}
}

signed main(){
	open("formula");
	scanf( "%d%d%d%d", &N, &a, &b, &c ), M = N << 1;
	fp( i, 1, N ) scanf( "%d", l + i );
	fp( i, 1, N ) scanf( "%d", t + i );
	// if ( N <= 1e3 ) return brute::solve(), 0;
	fac[0] = 1;
	fp( i, 1, M ) fac[i] = (i64)fac[i - 1] * i % mod;
	inv[M] = Pow(fac[M]);
	fd( i, M, 1 ) inv[i - 1] = (i64)inv[i] * i % mod;
	pa[0] = pb[0] = 1;
	fp( i, 1, N ) pa[i] = (i64)pa[i - 1] * a % mod, pb[i] = (i64)pb[i - 1] * b % mod;
	int ans(0);
	fp( i, 2, N ) ans = (ans + ((i64)l[i] * pa[N - 1] * pb[N - i] + (i64)t[i] * pa[N - i] * pb[N - 1]) % mod * calc(N - i + 1, N - 1)) % mod;
	if ( c ){
		int s(1);
		fp( i, 0, N - 2 ) ans = (ans + (i64)s * c) % mod, s = (i64)s * (a + b) % mod;
		fp( i, 0, N - 3 ){
			s = (s - ((i64)pb[N - 1] * pa[i] + (i64)pa[N - 1] * pb[i]) * C(N - 2 + i, i) % mod + mod) % mod,
			ans = (ans + (i64)s * c) % mod, s = (i64)s * (a + b) % mod;
		}
	}
	printf( "%d\n", ans );
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章