U537283 方格数 题解

原题传送门


先考虑 \(k = 0\) 的情况:

\(\Large\boxed{···}\boxed{0}\boxed{0}\boxed{1}\boxed{2}\boxed{3}\)

这个填数的形式不太好操作(也是我出题故意这样改的)

可以发现它的操作很像数字,比如可以拆分成
\(\Large\boxed{0}\boxed{0}\boxed{0}\boxed{1}\boxed{2}+\Large\boxed{0}\boxed{0}\boxed{1}\boxed{1}\boxed{1}\)

诶,那继续拆分显然就成了 \(1 + 11 + 111\)

因此我们可以设一个函数 \(f(n)\)

\( \begin{aligned} f(n) &= 111···111 \ (n个1) \\ &= 10^0 + 10^1 + ··· + 10^{n-1} \\ &= \frac{10^n-1}{9} \end{aligned} \)

所以

\( \begin{aligned} f(1)+f(2)+···+f(n) &= \frac{10^1-1}{9} + \frac{10^2-1}{9} + ··· + \frac{10^n-1}{9} \\ &= \frac{10^1 + 10^2 + ··· + 10^n}{9} - \frac{n}{9} \\ &= \frac{10^0 + 10^1 + 10^2 + ··· + 10^n}{9} - \frac{n+1}{9} \\ &= \frac{f(n+1) - n - 1}{9} \\ &= \frac{10^{n+1}-9n - 10}{81} \end{aligned} \)

再以此类推所有的 \(k\)

对于所有 \(k\),我们都可以设一个函数

\( \begin{aligned} f(n) &= 10101···10101 \ (n个1,间隔k个0) \\ &= 10^0 + 10^{k+1} + ··· + 10^{{(k+1)}{(n-1)}} \\ &= \frac{10^{(k+1)n}-1}{10^{k+1}-1} \end{aligned} \)

所以

\( \begin{aligned} f(1)+f(2)+···+f(n) &= \frac{10^{k+1}-1}{10^{k+1}-1} + \frac{10^{2(k+1)}-1}{10^{k+1}-1} + ··· + \frac{10^{n(k+1)}-1}{10^{k+1}-1} \\ &= \frac{10^{k+1} + 10^{2(k+1)} + ··· + 10^{n(k+1)}}{10^{k+1}-1} - \frac{n}{10^{k+1}-1} \\ & = \frac{f(n+1)-n-1}{10^{k+1}-1} \\ & = \frac{10^{(k+1)(n+1)}-(n+1)10^{k+1} + n}{(10^{k+1}-1)^2} \end{aligned} \)

(终于完结了,写了好久)

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define debug(x) cout<<#x<<" = "<<x<<endl;
const int M = 1e9 + 7;
ll n, k;
inline ll read(){
	ll s=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){s=(s<<1)+(s<<3)+(c^48);c=getchar();}
	return s*f;
}
ll Pow(ll x, ll y){
	ll ans=1;
	while(y){
		if(y&1)ans = ans*x%M;
		x = x*x%M;
		y >>= 1;
	}
	return ans;
}
int main(){
	int T = read();
	while(T--){
		n = read(), k = read();
		ll t = Pow(10, k+1);
		cout << (Pow(10, (n+1)*(k+1)) - (n+1) * t % M + n + M) % M * Pow((t-1)*(t-1)%M, M-2) % M << endl;
	}
	return 0;
}
posted @ 2025-02-22 09:50  今添  阅读(16)  评论(0)    收藏  举报