题解:P17064 [JRKSJ R10 热身赛] Infinite Strife,

这就是我们 Implicit 老师出的题吗!畏惧了。

顺着赛时思路摸出来的偏数论的做法。

设向右、向上各走了 \(k\) 步,则可以确定向右上走了 \(2n-k\) 步,可以得到

\[a_n=\sum_{k=0}^{\lfloor n/2\rfloor}\frac{n!}{k!k!(n-2k)!}=\sum_{k=0}^{\lfloor n/2\rfloor}\binom{n}{k,k,n-2k} \]

\(n\)\(11\) 进制分解成 \(\sum n_j11^j\)\(k\) 分解成 \(\sum k_j11^j\),若对于所有 \(j\) 都有 \(n_j\geq k_j\),则由 Lucas 定理,

\[\begin{align*} &\binom{n}{k,k,n-2k}\\ =&\binom{n}{k}\binom{n-k}{k}\\ =&\prod\binom{n_j}{k_j}\binom{n_j-k_j}{k_j}\\ =&\prod\binom{n_j}{k_j,k_j,n-2k_j} \end{align*} \]

否则若存在 \(n_j<k_j\),则 \(\dbinom{n}{k}\bmod{11}=0\),可以直接扔掉。

由此不难推出 \(a_{11q+r}\equiv a_qa_r\pmod{11}\)。直接做时间复杂度为 \(\mathcal{O}(cn)\),可以通过 Subtask 2。

感觉上这个前缀积的变换很怪异。注意到 \(2\) 是模 \(11\) 意义下的原根,因此每个 \([0,10]\) 以内的数都可以唯一对应到一个 \(2\) 的幂。设 \(a_r\equiv 2^{w_r}\pmod{11}\),则 \(a_n\equiv 2^{s(n)}\pmod{11}\),其中 \(s(n)=\sum w_{n_j}\)。这样前缀积变换就转化成了前缀和变换,根据经典公式,变换 \(c\) 次后 \(a_n\) 对应的指数为

\[\sum_{i=0}^n\binom{n-i+c-1}{c-1}s(i) \]

根据欧拉定理,我们求出这个式子 \(\bmod{10}\) 的值即可。

观察到 \(\dbinom{x+c-1}{c-1}\bmod{10}\) 具有一定的周期性。具体来说,考察范德蒙德卷积:

\[\dbinom{x+T+c-1}{c-1}=\sum_{i=0}^{c-1}\dbinom{x+c-1}{c-1-i}\dbinom{T}{i} \]

对于某个质数 \(p\),若取 \(T=p^k\) 为最小的 \(\geq c\)\(p\) 的幂,则对于所有 \(1\leq i\leq c-1\),都有 \(\dbinom Ti\equiv 0\pmod{p}\),于是

\[\dbinom{x+T+c-1}{c-1}\equiv\dbinom{x+c-1}{c-1}\pmod{p} \]

在模 \(10\) 意义下,由 CRT,可以取

\[T=2^{1+\lfloor\log_2(c-1)\rfloor}5^{1+\lfloor\log_5(c-1)\rfloor} \]

于是我们只需要对于每个 \(0\leq r<T\),求出

\[\sum_{i=0}^n[i\bmod{T}=r]s(i) \]

数位 DP。从高位到低位 DP,设 \(f_{r,lim}\ (lim\in\{0,1\})\) 表示当前满足条件的数有多少个,其中 \(r\) 表示 \(\bmod{T}\) 的值,\(lim\) 表示是否贴着 \(n\) 的上界。\(g_{r,lim}\) 表示当前满足条件的数的 \(s(i)\) 之和。转移为

\[\begin{align*} f'_{r',lim'}&\gets f_{r,lim}\\ g'_{r',lim'}&\gets g_{r,lim}+w_df_{r,lim} \end{align*} \]

DP 部分时间复杂度为 \(\mathcal{O}(dT\log_{d}n)\),其中 \(d=11\)

求答案时可以直接计算

\[\sum_{r=0}^{T-1}\binom{((n-r)\bmod{T})+c-1}{c-1}(g_{r,0}+g_{r,1})\bmod{10} \]

组合数 \(\bmod{10}\) 可以用 Lucas 定理算出 \(\bmod{2}\)\(\bmod{5}\) 的值,再用 CRT 合并。

\(c\leq 500\) 时,\(T\leq 320000\),这个做法可以通过 Subtask 6。

对于更大的 \(c\),考虑分别求出 \(\bmod{2}\)\(\bmod{5}\) 的值,再用 CRT 合并。此时 \(T_2\leq 32768\)\(T_5\leq 78125\),可以承受。时间复杂度为 \(\mathcal{O}(T_2\log_2 T_2+T_5\log_5 T_5+d(T_2+T_5)\log_{d}n)\),其中 \(d=11\)

主要代码
int tc, c, T;
int w[] = {0, 0, 8, 7, 3, 7, 6, 3, 7, 2, 5};
int C[6][6];
ll n;
vector<int> digits;

template<ui mod>
ModIntBase<ui, mod> lucas(int n, int m) {
	if (n < m) return 0;
	if (n < mod && m < mod) return C[n][m];
	return lucas<mod>(n % mod, m % mod) * lucas<mod>(n / mod, m / mod);
}

template<ui mod>
int calc() {
	using mint = ModIntBase<ui, mod>;
	int T = 1;
	while (T <= c - 1) T *= mod;
	vector<array<mint, 2>> f(T), g(T), nf(T), ng(T);
	f[0][1] = 1;
	g[0][1] = 0;
	for (int x : digits) {
		for (int r = 0; r < T; ++r)
			for (int lim : {0, 1})
				nf[r][lim] = ng[r][lim] = 0;
		for (int r = 0; r < T; ++r) {
			for (int lim : {0, 1}) {
				if (!f[r][lim].val() && !g[r][lim].val()) continue;
				int up = lim ? x : 10;
				for (int d = 0; d <= up; ++d) {
					int nr = (r * 11 + d) % T;
					bool nlim = lim && d == up;
					nf[nr][nlim] += f[r][lim];
					ng[nr][nlim] += g[r][lim] + f[r][lim] * w[d];
				}
			}
		}
		for (int r = 0; r < T; ++r) {
			for (int lim : {0, 1}) {
				f[r][lim] = nf[r][lim];
				g[r][lim] = ng[r][lim];
			}
		}
	}
	ModIntBase<ui, mod> sum = 0;
	for (int r = 0; r < T; ++r)
		sum += lucas<mod>((n - r + T) % T + c - 1, c - 1) * (g[r][0] + g[r][1]);
	return sum.val();
}

mint11 qpow(mint11 a, ll b) {
	mint11 res = 1;
	for (; b; b >>= 1) {
		if (b & 1) res *= a;
		a *= a;
	}
	return res;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	for (int i = 0; i <= 5; ++i)
		for (int j = 0; j <= 5; ++j)
			C[i][j] = !j ? 1 : C[i - 1][j - 1] + C[i - 1][j];
	cin >> tc;
	while (tc--) {
		cin >> n >> c;
		digits.clear();
		for (ll i = n; i; i /= 11) digits.emplace_back(i % 11);
		reverse(digits.begin(), digits.end());
		cout << qpow(2, (calc<2>() * 5 + calc<5>() * 6) % 10) << '\n';
	}
	return 0;
}
posted @ 2026-07-05 15:28  P2441M  阅读(15)  评论(0)    收藏  举报