题目链接: [ S H O I 2015 ] 超 能 粒 子 炮 ⋅ 改 \rm [SHOI2015]超能粒子炮·改 [SHOI2015]超能粒子炮⋅改
感谢 V e n u s \rm Venus Venus 神仙帮助完成 LaTeX \LaTeX LATEX 公式
显然题目让我们求的是 [ ∑ i = 0 k ( n i ) ] % p \rm \left[\sum\limits_{i=0}^k\binom ni\right]\%p [i=0∑k(in)]%p 的值,其中 p = 2333 \rm p=2333 p=2333
设 sum ( n , k ) = [ ∑ i = 0 k ( n i ) ] % p \rm \operatorname{sum}(n,k)=\left[\sum\limits_{i=0}^k\binom ni\right]\%p sum(n,k)=[i=0∑k(in)]%p
然后我们开始推式子(大波 LaTeX \LaTeX LATEX 公式警告):
sum ( n , k ) = [ ∑ i = 0 k ( n i ) ] % p (为保证界面美观,以下省略%p) = ∑ i = 0 k ( n / p i / p ) ( n % p i % p ) (卢卡斯定理) = [ ∑ i = 0 p − 1 ( n / p 0 ) ( n % p i ) ] + [ ∑ i = 0 p − 1 ( n / p 1 ) ( n % p i ) ] + ⋯ + [ ∑ i = 0 p − 1 ( n / p k / p − 1 ) ( n % p i ) ] + [ ∑ i = 0 k % p ( n / p k / p ) ( n % p i ) ] (整除分块) = [ ( n / p 0 ) ∑ i = 0 p − 1 ( n % p i ) ] + [ ( n / p 1 ) ∑ i = 0 p − 1 ( n % p i ) ] + ⋯ + [ ( n / p k / p − 1 ) ∑ i = 0 p − 1 ( n % p i ) ] + [ ( n / p k / p ) ∑ i = 0 k % p ( n % p i ) ] = [ ∑ i = 0 p − 1 ( n % p i ) ] × [ ∑ j = 0 k / p − 1 ( n / p j ) ] + ( n / p k / p ) ∑ i = 0 k % p ( n % p i ) \begin{aligned} \rm \operatorname{sum}(n,k) & =\rm \left[ \sum_{i=0}^k\binom ni \right] \%p \quad\color{#66ccff}\textbf{(为保证界面美观,以下省略\%p)}\\ & =\rm \sum_{i=0}^k\binom{n/p}{i/p}\binom{n\%p}{i\%p} \color{#66ccff}\textbf{(卢卡斯定理)}\\ & =\rm \left[ \sum_{i=0}^{p-1}\binom{n/p}0\binom{n\%p}i\right] +\left[\sum_{i=0}^{p-1}\binom{n/p}1\binom{n\%p}i\right]+\cdots \\ & \rm \quad\ +\left[\sum_{i=0}^{p-1}\binom{n/p}{k/p-1} \binom{n\%p}i\right] +\left[\sum_{i=0}^{k\% p}\binom{n/p}{k/p}\binom{n\%p}i \right] \color{#66ccff}\textbf{(整除分块)}\\ & =\rm \left[\binom{n/p}0\sum_{i=0}^{p-1}\binom{n\%p}i\right] +\left[\binom{n/p}1\sum_{i=0}^{p-1}\binom{n\%p}i\right]+\cdots \\ & \rm\quad\ +\left[\binom{n/p}{k/p-1}\sum_{i=0}^{p-1}\binom{n\%p}i\right] +\left[\binom{n/p}{k/p}\sum_{i=0}^{k\%p}\binom{n\%p}i\right] \\ & =\rm \left[\sum_{i=0}^{p-1}\binom{n\%p}i\right] \times\left[\sum_{j=0}^{k/p-1}\binom{n/p}j\right] +\binom{n/p}{k/p}\sum_{i=0}^{k\%p}\binom{n\%p}i \end{aligned} sum(n,k)=[i=0∑k(in)]%p(为保证界面美观,以下省略%p)=i=0∑k(i/pn/p)(i%pn%p)(卢卡斯定理)=[i=0∑p−1(0n/p)(in%p)]+[i=0∑p−1(1n/p)(in%p)]+⋯ +[i=0∑p−1(k/p−1n/p)(in%p)]+⎣⎡i=0∑k%p(k/pn/p)(in%p)⎦⎤(整除分块)=[(0n/p)i=0∑p−1(in%p)]+[(1n/p)i=0∑p−1(in%p)]+⋯ +[(k/p−1n/p)i=0∑p−1(in%p)]+⎣⎡(k/pn/p)i=0∑k%p(in%p)⎦⎤=[i=0∑p−1(in%p)]×⎣⎡j=0∑k/p−1(jn/p)⎦⎤+(k/pn/p)i=0∑k%p(in%p)
再套用一下 sum \operatorname{sum} sum 的定义就有:
sum ( n , k ) = [ sum ( n % p , p − 1 ) × sum ( n / p , k / p − 1 ) + ( n / p k / p ) sum ( n % p , k % p ) ] % p \rm \operatorname{sum}(n,k)= \left [\operatorname{sum}(n\%p,p-1) \times\operatorname{sum}(n/p,k/p-1) +\binom{n/p}{k/p}\operatorname{sum}(n\%p,k\%p)\right] \%p sum(n,k)=[sum(n%p,p−1)×sum(n/p,k/p−1)+(k/pn/p)sum(n%p,k%p)]%p
化简完毕。那么各部分如何处理呢?
sum ( n % p , p − 1 ) , sum ( n % p , k % p ) 的 参 数 都 小 于 p , 可 以 预 处 理 出 来 ; 2333 是 质 数 , 所 以 ( n / p k / p ) 显 然 可 以 用 L u c a s 搞 出 来 ; sum ( n / p , k / p − 1 ) 可 以 递 归 求 解 。 \begin{aligned} & \rm \operatorname{sum}(n\%p,p-1),\operatorname{sum}(n\%p,k\%p) 的参数都小于 p ,可以预处理出来; \\ & \rm 2333是质数,所以\binom{n/p}{k/p}显然可以用Lucas搞出来; \\ & \rm \operatorname{sum}(n/p,k/p-1)可以递归求解。 \end{aligned} sum(n%p,p−1),sum(n%p,k%p)的参数都小于p,可以预处理出来;2333是质数,所以(k/pn/p)显然可以用Lucas搞出来;sum(n/p,k/p−1)可以递归求解。
代码
#include
#include
#define getc (l==r&&(r=(l=f)+fread(f,1,1<<21,stdin),l==r)?EOF:*l++)
//fread优化快读
typedef long long ll;
const int p=2333;
char f[1<<21],*l=f,*r=f;
inline ll read() { //快读
ll x=0; char ch=getc;
while (!isdigit(ch)) ch=getc;
while (isdigit(ch)) { x=x*10+(ch^48); ch=getc; }
return x;
}
int c[p][p],s[p][p];
void work() {
//杨辉三角预处理组合数
for (int i=0; i=p?s[n%p][p-1]*S(n/p,m/p-1)%p:0);
(n/p>=m/p)&&(ans+=C(n/p,m/p)*s[n%p][m%p]%p);
return ans%p;
}
int main() {
work();
int T=read();
while (T--) {
ll n=read(),m=read();
printf("%d\n",S(n,m));
}
}