多校联测13 可

题目大意

k k k个在 [ 0 , x ] [0,x] [0,x]范围内的随机整数 a 1 , a 2 , … , a k a_1,a_2,\dots,a_k a1,a2,,ak,设 f ( x ) f(x) f(x)表示 x x x的所有非零位的积,例如 f ( 0 ) = 1 , f ( 1145141919810 ) = 1 × 1 × 4 × 5 × 1 × 4 × 1 × 9 × 1 × 9 × 8 × 1 f(0)=1,f(1145141919810)=1\times 1\times 4\times 5\times 1\times 4\times 1\times 9\times 1\times 9\times 8\times 1 f(0)=1,f(1145141919810)=1×1×4×5×1×4×1×9×1×9×8×1。求 f ( ∑ i = 1 k a i ) f(\sum\limits_{i=1}^ka_i) f(i=1kai)的期望值,输出答案乘 ( x + 1 ) k (x+1)^k (x+1)k后的值。

1 ≤ x ≤ 1 0 1 0 4 , 1 ≤ k ≤ 20 , x + 1 ≢ 0 ( m o d 1 0 9 + 7 ) 1\leq x\leq 10^{10^4},1\leq k\leq 20,x+1\not\equiv0\pmod{10^9+7} 1x10104,1k20,x+10(mod109+7)

时间限制 6000 m s 6000ms 6000ms


题解

题意即计算在所有情况下的 f ( ∑ i = 1 k a i ) f(\sum\limits_{i=1}^ka_i) f(i=1kai)的总和。

考虑计算 ∑ i = 1 k a i = n \sum\limits_{i=1}^ka_i=n i=1kai=n时的方案数 g ( n ) g(n) g(n)

g ( n ) = ∑ i = 0 k ( − 1 ) i × ( k i ) × ( n − i ( x + 1 ) + k − 1 k − 1 ) g(n)=\sum\limits_{i=0}^k(-1)^i\times \binom ki\times \binom{n-i(x+1)+k-1}{k-1} g(n)=i=0k(1)i×(ik)×(k1ni(x+1)+k1)

这个式子是怎么得到的呢?运用容斥,钦定有 i i i个数是 ≥ x + 1 \geq x+1 x+1的,乘上不同的分配位置 ( k i ) \binom ki (ik)。后面是插板法,将 n − i ( x + 1 ) n-i(x+1) ni(x+1)分为 k k k个数,然后在对应的位置加上 x + 1 x+1 x+1,来保证钦定为 ≥ x + 1 \geq x+1 x+1的这些数分配到的值 ≥ x + 1 \geq x+1 x+1

注意,当 n > k x n>kx n>kx时,显然任意的 ∑ i = 1 k a i \sum\limits_{i=1}^ka_i i=1kai都不等于 n n n,所以此时 g ( n ) = 0 g(n)=0 g(n)=0

得到了 g ( n ) g(n) g(n),我们就可以推答案了。答案为

∑ i = 0 k x f ( i ) g ( i ) = ∑ i = 0 k x f ( i ) ∑ j = 0 k ( − 1 ) j ( k j ) ( i − j ( x + 1 ) + k − 1 k − 1 ) = ∑ j = 0 k ( − 1 ) j ( k j ) ∑ i = 0 k x f ( i ) × [ i − j ( x + 1 ) + k − 1 ] ! ( k − 1 ) ! [ i − j ( x + 1 ) ] ! = 1 ( k − 1 ) ! ∑ j = 0 k ( − 1 ) j ( k j ) ∑ i = 0 k x f ( i ) × [ i − j ( x + 1 ) ] k − 1 ‾ = 1 ( k − 1 ) ! ∑ j = 0 k ( − 1 ) j ( k j ) ∑ l = 0 k − 1 v j , l ∑ i = 0 k x f ( i ) i l \begin{aligned} \sum\limits_{i=0}^{kx}f(i)g(i)&=\sum\limits_{i=0}^{kx}f(i)\sum\limits_{j=0}^k(-1)^j\binom kj\binom{i-j(x+1)+k-1}{k-1} \\ &=\sum\limits_{j=0}^k(-1)^j\binom kj\sum\limits_{i=0}^{kx}f(i)\times \dfrac{[i-j(x+1)+k-1]!}{(k-1)![i-j(x+1)]!} \\ &=\dfrac{1}{(k-1)!}\sum\limits_{j=0}^k(-1)^j\binom kj\sum\limits_{i=0}^{kx}f(i)\times [i-j(x+1)]^{\underline{k-1}} \\ &=\dfrac{1}{(k-1)!}\sum\limits_{j=0}^k(-1)^j\binom kj\sum\limits_{l=0}^{k-1}v_{j,l}\sum\limits_{i=0}^{kx}f(i)i^l \end{aligned} i=0kxf(i)g(i)=i=0kxf(i)j=0k(1)j(jk)(k1ij(x+1)+k1)=j=0k(1)j(jk)i=0kxf(i)×(k1)![ij(x+1)]![ij(x+1)+k1]!=(k1)!1j=0k(1)j(jk)i=0kxf(i)×[ij(x+1)]k1=(k1)!1j=0k(1)j(jk)l=0k1vj,li=0kxf(i)il

其中 [ i − j ( x + 1 ) ] k − 1 ‾ [i-j(x+1)]^{\underline{k-1}} [ij(x+1)]k1为下降幂, n k ‾ = n ( n − 1 ) ⋯ ( n − k + 1 ) n^{\underline k}=n(n-1)\cdots(n-k+1) nk=n(n1)(nk+1)。最后一行的 v j , l v_{j,l} vj,l表示 [ i − j ( x + 1 ) ] k − 1 ‾ [i-j(x+1)]^{\underline{k-1}} [ij(x+1)]k1 i l i^l il的系数。,我们可以 O ( k 3 ) O(k^3) O(k3)求出所有 v j , l v_{j,l} vj,l

那么,我们只需要求出 ∑ i = 0 t f ( i ) i l \sum\limits_{i=0}^tf(i)i^l i=0tf(i)il,我们可以用数位 D P DP DP来求。从大到小枚举当前这一位的取值,设当前是第 n o w now now位,取值为 x x x。设 d p n o w , j = ∑ i f ( i ) i j dp_{now,j}=\sum\limits_i f(i)i^j dpnow,j=if(i)ij,其中 i i i满足 i i i的后 n o w − 1 now-1 now1位都为 0 0 0。那么,

d p n o w , t = ∑ i ∑ x f ( i + x × 1 0 n o w ) × ( i + x × 1 0 n o w ) t = ∑ i ∑ x f ( i ) × f ( x ) × ∑ d = 0 t ( t d ) i d ( x × 1 0 n o w ) t − d = ∑ d = 0 t ( t d ) × ( ∑ i f ( i ) i d ) × [ ∑ x f ( x ) × ( x × 1 0 n o w ) t − d ] = ∑ d = 0 t ( t d ) d p n o w + 1 , d × [ ∑ x f ( x ) × ( x × 1 0 n o w ) t − d ] \begin{aligned} dp_{now,t}&=\sum\limits_i\sum\limits_xf(i+x\times 10^{now})\times (i+x\times 10^{now})^t \\ &=\sum\limits_i\sum\limits_xf(i)\times f(x)\times \sum\limits_{d=0}^t\binom tdi^d(x\times 10^{now})^{t-d} \\ &=\sum\limits_{d=0}^t\binom td\times (\sum_if(i)i^d)\times [\sum_xf(x)\times (x\times 10^{now})^{t-d}] \\ &=\sum\limits_{d=0}^t\binom tddp_{now+1,d}\times [\sum_xf(x)\times (x\times 10^{now})^{t-d}] \end{aligned} dpnow,t=ixf(i+x×10now)×(i+x×10now)t=ixf(i)×f(x)×d=0t(dt)id(x×10now)td=d=0t(dt)×(if(i)id)×[xf(x)×(x×10now)td]=d=0t(dt)dpnow+1,d×[xf(x)×(x×10now)td]

这样,我们就可以用 d p n o w + 1 , d dp_{now+1,d} dpnow+1,d来求 d p n o w , t dp_{now,t} dpnow,t了。

观察 ∑ i = 0 k x f ( i ) g ( i ) \sum\limits_{i=0}^{kx}f(i)g(i) i=0kxf(i)g(i)这个式子,在上面得知 i > k x 时 i>kx时 i>kx g ( i ) = 0 g(i)=0 g(i)=0,所以增大 i i i的上限并不会增加这个式子的结果。为了方便计算,我们将 i i i的上限定为 1 0 w + 3 − 1 10^{w+3}-1 10w+31(其中 w w w x x x的位数),显然 1 0 w + 3 − 1 ≥ k x 10^{w+3}-1\geq kx 10w+31kx。这样的话,每一位数都可以取 0 0 0 9 9 9中的每一个数。

不过,还有一个问题。在上面得到下降幂的部分,当 i < j ( x + 1 ) ii<j(x+1)时, ( i − j ( x + 1 ) + k − 1 k − 1 ) \binom{i-j(x+1)+k-1}{k-1} (k1ij(x+1)+k1)应该等于 0 0 0,但变为下降幂之后却变为负数。不过这个很好处理,只要将 i i i的下限定为 j ( x + 1 ) j(x+1) j(x+1)即可避免这种情况,而且不影响结果。

那么,就变为求 ∑ i = j ( x + 1 ) 1 0 w + 3 − 1 f ( i ) i l \sum\limits_{i=j(x+1)}^{10^{w+3}-1}f(i)i^l i=j(x+1)10w+31f(i)il了。其实求法是类似的,只是要将 d p n o w , t dp_{now,t} dpnow,t拆成两个数组 f n o w , t f_{now,t} fnow,t g n o w , t g_{now,t} gnow,t,用 f n o w , t f_{now,t} fnow,t存当前已经枚举的数的各位都等于 j ( x + 1 ) j(x+1) j(x+1)的各位,用 g n o w , t g_{now,t} gnow,t存当前已经枚举的数的各位都大于 j ( x + 1 ) j(x+1) j(x+1)的各位,再进行 D P DP DP,即可保证 i ≥ j ( x + 1 ) i\geq j(x+1) ij(x+1)。转移式如下:

g n o w , t = ∑ d = 0 t ( t d ) g n o w + 1 , d × [ ∑ x = 0 9 f ( x ) × ( x × 1 0 n o w ) t − d ] + ∑ d = 0 t ( t d ) f n o w + 1 , d × [ ∑ x = A 9 f ( x ) × ( x × 1 0 n o w ) t − d ] g_{now,t}=\sum\limits_{d=0}^t\binom tdg_{now+1,d}\times [\sum_{x=0}^9f(x)\times (x\times 10^{now})^{t-d}]+\sum\limits_{d=0}^t\binom tdf_{now+1,d}\times [\sum_{x=A}^9f(x)\times (x\times 10^{now})^{t-d}] gnow,t=d=0t(dt)gnow+1,d×[x=09f(x)×(x×10now)td]+d=0t(dt)fnow+1,d×[x=A9f(x)×(x×10now)td]

f n o w , t = ∑ d = 0 t ( t d ) f n o w + 1 , d × [ f ( A ) × ( A × 1 0 n o w ) t − d ] f_{now,t}=\sum\limits_{d=0}^t\binom tdf_{now+1,d}\times [f(A)\times (A\times 10^{now})^{t-d}] fnow,t=d=0t(dt)fnow+1,d×[f(A)×(A×10now)td]

其中 A A A j ( x + 1 ) j(x+1) j(x+1)的从后往前的第 n o w now now位。

这些式子和上面的 d p n o w , t dp_{now,t} dpnow,t本质是一样的,只不过 f n o w , t f_{now,t} fnow,t的当前位只能填 A A A。为了保证 g n o w , t g_{now,t} gnow,t中算贡献的 i i i都大于 j ( x + 1 ) j(x+1) j(x+1),那分为两种情况:

  • i i i之前的位都比 j ( x + 1 ) j(x+1) j(x+1)大,则这一位无论是什么, i i i都比 j ( x + 1 ) j(x+1) j(x+1)大,所以可以任意填
  • i i i之前的位都等于 j ( x + 1 ) j(x+1) j(x+1),则这一位要填大于 A A A的数, i i i才能比 j ( x + 1 ) j(x+1) j(x+1)大,所以可以填 [ A + 1 , 9 ] [A+1,9] [A+1,9]中的数

为了可以这样转移, n o w now now要从大到小枚举(也就是从 i i i的高位到低位枚举),这就是为什么 n o w now now要从大到小枚举的原因。

c i , j = f ( i ) × ( i × 1 0 n o w ) j , d i , j = ∑ t = i 9 f ( i ) × ( i × 1 0 n o w ) j c_{i,j}=f(i)\times (i\times 10^{now})^j,d_{i,j}=\sum\limits_{t=i}^9f(i)\times (i\times 10^{now})^j ci,j=f(i)×(i×10now)j,di,j=t=i9f(i)×(i×10now)j,即 d i , j d_{i,j} di,j c i , j c_{i,j} ci,j的后缀和,我们可以提前求出 c i , j c_{i,j} ci,j d i , j d_{i,j} di,j,那么上面的 D P DP DP式变为

g n o w , t = ∑ d = 0 t ( t d ) g n o w + 1 , d × d 0 , t − d + ∑ d = 0 t ( t d ) f n o w + 1 , d × d A + 1 , t − d g_{now,t}=\sum\limits_{d=0}^t\binom tdg_{now+1,d}\times d_{0,t-d}+\sum\limits_{d=0}^t\binom tdf_{now+1,d}\times d_{A+1,t-d} gnow,t=d=0t(dt)gnow+1,d×d0,td+d=0t(dt)fnow+1,d×dA+1,td

f n o w , t = ∑ d = 0 t ( t d ) f n o w + 1 , t c A , t − d f_{now,t}=\sum\limits_{d=0}^t\binom td f_{now+1,t}c_{A,t-d} fnow,t=d=0t(dt)fnow+1,tcA,td

d p n o w , t dp_{now,t} dpnow,t的值为两者相加,即 d p n o w , t = f n o w , t + g n o w , t dp_{now,t}=f_{now,t}+g_{now,t} dpnow,t=fnow,t+gnow,t。再按上面的式子推出 ∑ i = j ( x + 1 ) 1 0 w + 3 − 1 f ( i ) g ( i ) \sum\limits_{i=j(x+1)}^{10^{w+3}-1}f(i)g(i) i=j(x+1)10w+31f(i)g(i),即可得到答案。

时间复杂度为 O ( k 3 lg ⁡ x ) O(k^3\lg x) O(k3lgx)

code

#include
using namespace std;
const int N=100000;
const long long mod=1e9+7;
int len;
long long ans=0,k,num,a[N+5],b[N+5],w[15][25],sw[15][25];
long long jc[N+5],ny[N+5],tn[N+5],F[25],G[25],C[25][25],h[25][25],f[N+5][25],g[N+5][25];
char ch[N+5];
long long mi(long long t,long long v){
	if(!v) return 1;
	long long re=mi(t,v/2);
	re=re*re%mod;
	if(v&1) re=re*t%mod;
	return re;
}
void init(){
	jc[0]=1;
	for(int i=1;i<=N;i++) jc[i]=jc[i-1]*i%mod;
	ny[N]=mi(jc[N],mod-2);
	for(int i=N-1;i>=0;i--) ny[i]=ny[i+1]*(i+1)%mod;
}
long long gt(){
	memset(f,0,sizeof(f));
	memset(g,0,sizeof(g));
	f[len+1][0]=1;
	num=0;
	for(int now=len,A;now>=0;now--){
		A=b[now];
		for(int i=9;i>=0;i--){
			long long tmp=i*tn[now]%mod;
			w[i][0]=sw[i][0]=max(i,1);
			sw[i][0]=(sw[i][0]+sw[i+1][0])%mod;
			for(int j=1;j<=k-1;j++){
				w[i][j]=sw[i][j]=w[i][j-1]*tmp%mod;
				sw[i][j]=(sw[i][j]+sw[i+1][j])%mod;
			}
		}
		for(int i=0;i<k;i++){
			for(int j=0;j<=i;j++){
				F[j]=f[now+1][j]*C[i][j]%mod;
				G[j]=g[now+1][j]*C[i][j]%mod;
			}
			for(int j=0;j<=i;j++){
				g[now][i]=(g[now][i]+G[j]*sw[0][i-j]+F[j]*sw[A+1][i-j])%mod;
				f[now][i]=(f[now][i]+F[j]*w[A][i-j])%mod;
			}
		}
		num=(num+A*tn[now])%mod;
	}
	h[0][0]=1;
	for(int i=1;i<k;i++){
		for(int j=0;j<k;j++){
			h[i][j]=(h[i-1][j]*(i-num)+h[i-1][j-1])%mod;
		}
	}
	long long re=0;
	for(int i=0;i<k;i++){
		re=(re+h[k-1][i]*(f[0][i]+g[0][i]))%mod;
	}
	return re;
}
int main()
{
	init();
	scanf("%lld",&k);
	scanf("%s",ch);
	len=strlen(ch);
	for(int i=0;i<len;i++) a[i]=ch[len-i-1]-'0';
	++a[0];len+=2;
	for(int i=0;i<=len;i++){
		if(a[i]>=10){
			a[i+1]+=a[i]/10;
			a[i]%=10;
		}
	}
	tn[0]=1;
	for(int i=1;i<=len;i++) tn[i]=tn[i-1]*10%mod;
	for(int i=0;i<=k;i++){
		C[i][0]=C[i][i]=1;
		for(int j=1;j<i;j++) C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
	}
	long long tmp=1;
	for(int i=0;i<=k;i++,tmp*=-1){
		ans=(ans+tmp*C[k][i]*gt())%mod;
		for(int j=0;j<=len;j++){
			b[j]+=a[j];
			if(b[j]>=10){
				b[j+1]+=b[j]/10;
				b[j]%=10;
			}
		}
	}
	for(int i=1;i<k;i++) ans=ans*mi(i,mod-2)%mod;
	ans=(ans+mod)%mod;
	printf("%lld",ans);
	return 0;
}

你可能感兴趣的:(题解,好题,题解,c++)