LOJ #138. 类欧几里得算法

题目
推导方式比较牛逼,一劳永逸
推公式最详细的博客
消去公式:
F ( k 1 , k 2 , n , a , b , c ) = i = 0 n i k 1 a i + b c k 2 = i = 0 n i k 1 ( a c i + b c + ( a m o d    c ) i + ( b m o d    c ) c ) k 2 = i = 0 n i k 1 p = 1 3 j p = k 2 k ! p = 1 3 j p ! × ( a c i ) j 1 b c j 2 ( a m o d    c ) i + ( b m o d    c ) c j 3 = p = 1 3 j p = k 2 k ! a c j 1 b c j 2 p = 1 3 j p ! F ( k 1 + j 1 , j 3 , n , a % c , b % c , c ) \begin{aligned}F(k_1,k_2,n,a,b,c) &= \sum_{i=0}^n i^{k_1} \left\lfloor\frac{ai+b}c\right\rfloor^{k_2} \\ &= \sum_{i=0}^ni^{k_1}(\lfloor \frac ac \rfloor i+\lfloor \frac bc \rfloor+\lfloor \frac {(a\mod c)i+(b\mod c)}c\rfloor)^{k_2} \\ &=\sum_{i=0}^ni^{k_1} \sum_{\sum_{p=1}^3{j_p} = k_2} \frac{k!}{\prod_{p=1}^3 j_p!} \times\\& \left(\left\lfloor \frac ac\right \rfloor i\right)^{j_1} \left\lfloor \frac bc \right\rfloor ^{j_2} \left\lfloor \frac {(a\mod c)i+(b\mod c)}c \right\rfloor^{j_3}\\ &=\sum_{\sum_{p=1}^3{j_p} = k_2} \frac{k!\left\lfloor\frac ac \right \rfloor^{j_1}\left \lfloor\frac bc \right \rfloor^{j_2}}{\prod_{p=1}^3 j_p!} F(k_1+j_1,j_3,n,a\% c,b\% c ,c) \end{aligned}

反转公式:
m = a n + b c 1 m = \left \lfloor \frac {an+b}c \right\rfloor - 1
F ( k 1 , k 2 , n , a , b , c ) = i = 0 n i k 1 a i + b c k 2 = i = 0 n i k 1 p [ 1 , k 2 ] , j p [ 0 , m ] p = 1 k 2 [ j p < a i + b c ] ( j p ) = i = 0 n i k 1 q = 0 m [ q < a i + b c ] [ ( q + 1 ) k 2 q k 2 ] ( q < a i + b c i > c q + c b 1 a ) = q = 0 m [ ( q + 1 ) k 2 q k 2 ] ( i = 0 n i k i = 0 c q + c b 1 a i k ) = [ ( m + 1 ) k 2 0 k 2 ] i = 0 n i k q = 0 m r = 0 k 2 1 ( k 2 r ) q r i = 0 c q + c b 1 a i k ( S k ( x ) = i = 0 x i k k + 1 S k ( x ) = i = 0 k + 1 a k , i x i ) = [ ( m + 1 ) k 2 0 k 2 ] i = 0 n i k r = 0 k 2 1 i = 0 k 1 + 1 ( k 2 i ) a k 1 , i q = 0 m q r c q + c b 1 a i = [ ( m + 1 ) k 2 0 k 2 ] i = 0 n i k r = 0 k 2 1 i = 0 k 1 + 1 ( k 2 i ) a k 1 , i F ( r , i , m , c , c b 1 , a ) \begin{aligned} F(k_1,k_2,n,a,b,c) &= \sum_{i=0}^n i^{k_1} \left\lfloor\frac{ai+b}c\right\rfloor^{k_2} \\ &=\sum_{i=0}^n i^{k_1}\sum_{\forall p\in[1,k_2],j_p\in[0,m]} \prod_{p=1}^{k_2} [j_p<\left \lfloor \frac{ai+b}c \right \rfloor ]\\ &(枚举j_p的最大值)\\ &=\sum_{i=0}^n i^{k_1} \sum_{q=0}^m \left[q < \left \lfloor \frac {ai+b}c \right \rfloor\right]\left[(q+1)^{k_2}-q^{k_2}\right]\\ &(q < \left \lfloor \frac {ai+b}c \right \rfloor等价于i>\left \lfloor \frac {cq+c-b-1}a \right \rfloor) \\ &=\sum_{q=0}^m\left[(q+1)^{k_2}-q^{k_2}\right ] (\sum_{i=0}^n i^k - \sum_{i=0}^{\left \lfloor \frac {cq+c-b-1}a \right \rfloor} i^k)\\ &=\left[(m+1)^{k_2}-0^{k_2}\right ]\sum_{i=0}^n i^k - \\&\sum_{q=0}^m\sum_{r=0}^{k_2-1}\binom{k_2}{r}q^r\sum_{i=0}^{\left \lfloor \frac {cq+c-b-1}a \right \rfloor} i^k\\ &(将函数S_k(x) = \sum_{i=0}^x i^k插值后得到其k+1次表达式写作\\ &S_k(x) = \sum_{i=0}^{k+1} a_{k,i}x^i)\\ &=\left[(m+1)^{k_2}-0^{k_2}\right ]\sum_{i=0}^n i^k-\\ &\sum_{r=0}^{k_2-1}\sum_{i=0}^{k_1+1} \binom{k_2}{i}a_{k_1,i}\sum_{q=0}^mq^{r}\left\lfloor\frac {cq+c-b-1}a\right\rfloor^i\\ &=\left[(m+1)^{k_2}-0^{k_2}\right ]\sum_{i=0}^n i^k-\\ &\sum_{r=0}^{k_2-1}\sum_{i=0}^{k_1+1} \binom{k_2}{i}a_{k_1,i}F(r,i,m,c,c-b-1,a)\\ \end{aligned}
这个公式真的一点都不吓人。
但是我们需要注意我们在第二行做了的这个操作。
它在前后并不是完全相等(完全恒等)的。
k 2 = 0 k_2=0 时会出现我们 p [ 1 , k 2 ] , j p [ 0 , m ] p = 1 k 2 [ j p < a i + b c ] \sum_{\forall p\in[1,k_2],j_p\in[0,m]} \prod_{p=1}^{k_2} [j_p<\left \lfloor \frac{ai+b}c \right \rfloor ] 0 0 的情况,但实际上我们公式中这个位置应该是 1 1 才是正确的。
但是我们经过简单的计算和验证。
我们只需要让
F ( k 1 , k 2 , n , a , b , c ) = ( m + 1 ) k 2 i = 0 n i k r = 0 k 2 1 i = 0 k 1 + 1 ( k 2 i ) a k 1 , i F ( r , i , m , c , c b 1 , a ) F(k_1,k_2,n,a,b,c) =(m+1)^{k_2}\sum_{i=0}^n i^k-\\\sum_{r=0}^{k_2-1}\sum_{i=0}^{k_1+1} \binom{k_2}{i}a_{k_1,i}F(r,i,m,c,c-b-1,a)
即可解决问题。
注:实际上边界好像只用判 a = 0 a=0 ,别的判了也没多快,记忆化是真的快。

A C   C o d e \mathrm {AC \ Code}

#include<bits/stdc++.h>
#define maxn 15
#define mod 1000000007
#define LL long long
#define rep(i,j,k) for(int i=(j),LIM=(k);i<=LIM;i++)
#define per(i,j,k) for(int i=(j),LIM=(k);i>=LIM;i--)
using namespace std;

int inv[maxn]={1,1},fac[maxn]={1,1},invf[maxn]={1,1};
int Pow(int b,int k){
	int r = 1;
	for(;k;k>>=1,b=1ll*b*b%mod)
		if(k&1)
			r=1ll*r*b%mod;
	return r;
}

int C(int n,int m){
	static int c[maxn][maxn]={},f=0;
	if(!f){
		c[0][0]=f=1;
		rep(i,1,maxn-1) rep(j,c[i][0]=1,i) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod; 
	}
	return c[n][m];
}

int a[maxn][maxn];
int S(int n,int m){
	n %= mod;
	LL r = 0 , pw = 1;
	rep(j,0,m+1) r = (r + 1ll * a[m][j] * pw) , pw = 1ll * pw * n % mod;	
	return (r % mod + mod) % mod; 
}

int f[maxn][maxn][50];
int F(int k1,int k2,int n,int a,int b,int c,int dep=0){
	if(~f[k1][k2][dep]) return f[k1][k2][dep];
	if(a == 0) return f[k1][k2][dep] = (1ll * Pow(b/c,k2) * S(n,k1) % mod + mod) % mod;
	if(a>=c||b>=c){
		int r = 0 , A = a % c , B = b % c;a /= c , b /= c;
		int pwa[maxn]={},pwb[maxn]={};
		rep(j,pwa[0]=pwb[0]=1,k2) 
			pwa[j]=1ll*pwa[j-1]*a%mod,
			pwb[j]=1ll*pwb[j-1]*b%mod;
		rep(j1,0,k2) rep(j2,0,k2-j1){ int j3 = k2 - j1 - j2;
			r = (r + 1ll * pwa[j1] * pwb[j2] % mod * invf[j1] % mod * invf[j2] % mod * invf[j3] % mod * F(k1+j1,j3,n,A,B,c,dep+1)) % mod;
		}
		return f[k1][k2][dep] = ((1ll * r * fac[k2] % mod)+mod)%mod;
	}
	int m = (1ll * a * n + b) / c - 1 , r = 1ll * Pow(m+1,k2) * S(n,k1) % mod;
	rep(i,0,k2-1) rep(j,0,k1+1) r = (r - 1ll * C(k2 , i) * ::a[k1][j] % mod * F(i,j,m,c,c-b-1,a,dep+1)) % mod;
	return f[k1][k2][dep]=(r+mod)%mod;
}

int main(){
	rep(i,2,maxn-1) 
		inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod,
		fac[i]=1ll*fac[i-1]*i%mod,
		invf[i]=1ll*invf[i-1]*inv[i]%mod;
	a[0][1] = a[0][0] = 1;
	rep(i,1,maxn-2){
		rep(j,0,i+1) a[i][j] = C(i+1,j);
		rep(j,0,i-1) rep(k,0,j+1) 
			a[i][k] = (a[i][k] - 1ll * C(i+1,j) * a[j][k]) % mod;
		rep(j,0,i+1) a[i][j] = 1ll * a[i][j] * inv[i+1] % mod;
	}
	int T,n,a,b,c,k1,k2;
	for(scanf("%d",&T);T--;){
		scanf("%d%d%d%d%d%d",&n,&a,&b,&c,&k1,&k2);
		memset(f,-1,sizeof f);
		printf("%d\n",(F(k1,k2,n,a,b,c)+mod)%mod);
	}
}
发布了640 篇原创文章 · 获赞 97 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/qq_35950004/article/details/104068957