2025-12-30 hetao1733837 的刷题笔记
POJ3219 Binomial Coefficients
分析
模数改 2 是不是直接套卢卡斯?
小心 WA 哦!
假了,通过 L u c a s Lucas Lucas 定理我们可以得出,若 n & r = = r n\&r==r n&r==r 则为奇数,反之为偶数。
PKU 的 OJ 是啥啊?
正解
cpp
#include <iostream>
#include <cstdio>
using namespace std;
long long n, r;
int main(){
while (cin >> n >> r){
if ((n & r) == r){
cout << 1 << endl;
}
else{
cout << 0 << endl;
}
}
}
LG2480 [SDOI2010] 古代猪文
原题链接:[SDOI2010] 古代猪文
分析
按照 mhh 的思路,直接开造。这题是个指数取模,我需要知道这个怎么做。
我们要求的是 a b % p a^b \% p ab%p,但是,这里的 b b b 很大,也需要对 p p p 取模,我们知道 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1\pmod{p} ap−1≡1(modp)(本题 p = 999911659 p=999911659 p=999911659 是质数),所以 a b ≡ a b % ( p − 1 ) ( m o d p ) a^b\equiv a^{b\%(p-1)}\pmod{p} ab≡ab%(p−1)(modp)。
这个时候有出问题了,你 p p p 是质数,但是,你 p − 1 p-1 p−1 不是啊?你 p − 1 = 999911658 = 2 × 3 × 4679 × 35617 p-1=999911658=2\times 3 \times 4679 \times 35617 p−1=999911658=2×3×4679×35617,显然是个合数,但是,我已经完成了质因数分解,那直接那 C R T CRT CRT 拼一下不就行了吗?(虽然我不会这一步)
那么,看一下实现吧!
呃,我的暴力式子还需要放一下吗?
t m p = ∑ k = 1 n [ n % k = = 0 ] × C n k a n s = g t m p tmp = \sum\limits_{k=1}^{n}{[n \% k==0]\times C_{n}^{k}}\\ ans = g^{tmp} tmp=k=1∑n[n%k==0]×Cnkans=gtmp
总结一下:
①一个结论: a b ≡ a b % ( p − 1 ) ( m o d p ) a^b\equiv a^{b\%(p-1)}\pmod{p} ab≡ab%(p−1)(modp)
②引发一个质因数分解: 999911658 = 2 × 3 × 4679 × 35617 999911658=2\times 3 \times 4679 \times 35617 999911658=2×3×4679×35617
③然后 L u c a s Lucas Lucas 定理对这些质数分别取模
④最后 C R T CRT CRT 拼一下
⑤套一个快速幂结束......
我只有④自己写不出来!
糖了糖了!我们使用 L u c a s Lucas Lucas 定理对组合数取模之后,假设会得到 a 1 , a 2 , a 3 , a 4 a_1,a_2,a_3,a_4 a1,a2,a3,a4 四个数,然后,需求的最小的正整数 x x x 满足:
{ x ≡ a 1 ( m o d 2 ) x ≡ a 2 ( m o d 3 ) x ≡ a 3 ( m o d 4679 ) x ≡ a 4 ( m o d 35617 ) \begin{cases} x\equiv a_1\pmod{2}\\ x\equiv a_2\pmod{3}\\ x\equiv a_3\pmod{4679}\\ x\equiv a_4\pmod{35617}\\ \end{cases} ⎩ ⎨ ⎧x≡a1(mod2)x≡a2(mod3)x≡a3(mod4679)x≡a4(mod35617)
这不是 C R T CRT CRT 是啥?这么一看似乎都会了......但是代码......
正解
cpp
#include <bits/stdc++.h>
#define int long long
#define mod 999911658
using namespace std;
const int N = 40005; // > 35617
const int M = 5;
int n, g, fac[N], a[M], b[M] = {0, 2, 3, 4679, 35617};
int qpow(int a, int b, int p){
int res = 1;
a %= p;
while (b){
if (b & 1)
res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
void init(int p){
fac[0] = 1;
for (int i = 1; i <= p; i++){
fac[i] = fac[i - 1] * i % p;
}
}
int C(int n, int m, int p){
if (m > n)
return 0;
int inv1 = qpow(fac[m], p - 2, p);
int inv2 = qpow(fac[n - m], p - 2, p);
return fac[n] % p * inv1 % p * inv2 % p;
}
int Lucas(int n, int m, int p){
if (n == 0)
return 1;
if (n < m)
return 0;
return C(n % p, m % p, p) * Lucas(n / p, m / p, p) % p;
}
int val;
void CRT(){
for (int i = 1; i <= 4; i++){
val = (val + a[i] * (mod / b[i]) % mod * qpow(mod / b[i], b[i] - 2, b[i])) % mod;
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> g;
if (g % (mod + 1) == 0){
cout << 0;
return 0;
}
for (int k = 1; k <= 4; k++){
init(b[k]);
for (int i = 1; i <= sqrt(n); i++){
if (n % i == 0){
a[k] = (a[k] + Lucas(n, i, b[k])) % b[k];
if (i * i != n){
a[k] = (a[k] + Lucas(n, n / i, b[k])) % b[k];
}
}
}
}
CRT();
cout << qpow(g, val, mod + 1);
}
好的,我认为我会 e x L u c a s exLucas exLucas 了!那么,我来打个板子。
LG4720 【模板】扩展卢卡斯定理 / exLucas
分析
和上一题一样吧......只不过这次多了一个对 p p p 的质因数分解......
还是稍显困难啊/ll
一天终究只能深入理解一道紫题吗/ll
终究,还是做不到吗!
正解
cpp
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1000005;
int qpow(int a, int b, int p){
int res = 1;
while (b){
if (b & 1)
res = res * a % p;
a = a * a % p;
b >>= 1;
}
return res;
}
int exgcd(int a, int b, int &x, int &y){
if (!b){
x = 1;
y = 0;
return a;
}
int d = exgcd(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
return d;
}
int inv(int a, int p){
int x, y;
exgcd(a, p, x, y);
return (x % p + p) % p;
}
int F(int n, int p, int pk){
if (n == 0)
return 1;
int res = 1;
for (int i = 1; i <= pk; i++){
if (i % p)
res = res * i % pk;
}
res = qpow(res, n / pk, pk);
for (int i = 1; i <= n % pk; i++){
if (i % p)
res = res * i % pk;
}
return res * F(n / p, p, pk) % pk;
}
int G(int n, int p){
int res = 0;
while (n){
res += n / p;
n /= p;
}
return res;
}
int C(int n, int m, int p, int pk){
if (m > n)
return 0;
int f1 = F(n, p, pk);
int f2 = F(m, p, pk);
int f3 = F(n - m, p, pk);
int cnt = G(n, p) - G(m, p) - G(n - m, p);
int res = f1 * inv(f2, pk) % pk * inv(f3, pk) % pk;
res = res * qpow(p, cnt, pk) % pk;
return res;
}
void CRT(int a[], int b[], int k, int P, int &ans){
ans = 0;
for (int i = 1; i <= k; i++){
int M = P / b[i];
ans = (ans + a[i] * M % P * inv(M, b[i]) % P) % P;
}
}
int exLucas(int n, int m, int P){
if (m > n)
return 0;
int tmp = P;
int p[N], pk[N], a[N], cnt = 0; //质因子,质因子幂,模意义下的组合数、质因子个数
for (int i = 2; i * i <= tmp; i++){
if (tmp % i == 0){
p[++cnt] = i;
pk[cnt] = 1;
while (tmp % i == 0){
pk[cnt] *= i;
tmp /= i;
}
}
}
if (tmp > 1){
p[++cnt] = tmp;
pk[cnt] = tmp;
}
for (int i = 1; i <= cnt; i++){
a[i] = C(n, m, p[i], pk[i]);
}
int ans;
CRT(a, pk, cnt, P, ans);
return ans;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n, m, P;
cin >> n >> m >> P;
cout << exLucas(n, m, P) << "\n";
}
LG2675 《瞿葩的数字游戏》T3-三角圣地
原题链接:《瞿葩的数字游戏》T3-三角圣地
分析
我咋这么牛逼呢?我咋这么牛逼呢?我咋这么牛逼呢?
呃,还是没调出来,但是,显然是一个杨辉三角(二项式定理)+贪心,然后用 L u c a s Lucas Lucas 优化的。
正解
cpp
#include <bits/stdc++.h>
#define int long long
#define mod 10007
using namespace std;
const int N = 1000005;
int n, fac[N], a[N];
int qpow(int a, int b){
int res = 1;
while (b){
if (b & 1)
res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int C(int n, int m){
if (m > n)
return 0;
if (m == 0 || m == n)
return 1;
return fac[n] * qpow(fac[m], mod - 2) % mod * qpow(fac[n - m], mod - 2) % mod;
}
int Lucas(int n, int m){
if (m == 0)
return 1;
return C(n % mod, m % mod) * Lucas(n / mod, m / mod) % mod;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n;
fac[0] = 1;
for (int i = 1; i <= n; i++) {
fac[i] = fac[i - 1] * i % mod;
}
int cnt = 0;
for (int i = 1; i <= n; i += 2){
a[cnt++] = i;
}
cnt = n;
for (int i = 2; i <= n; i += 2) {
a[--cnt] = i;
}
int ans = 0;
for (int i = 0; i < n; i++){
ans = (ans + Lucas(n - 1, i) * a[i]) % mod;
}
cout << ans;
}
LG4345 [SHOI2015] 超能粒子炮·改
原题链接:[SHOI2015] 超能粒子炮·改
分析
行,擦眼镜把镜片掰下来了......
回去之前写一句:2333 是质数。
形式化的,题目要求:
∑ i = 0 k C n i ( m o d 2333 ) \sum\limits_{i=0}^{k}{C_{n}^{i}}\pmod{2333} i=0∑kCni(mod2333)
难点就在于 n , k ≤ 10 18 n,k\le 10^{18} n,k≤1018,还多测!所以需要预处理组合数。
去听了个选科讲座,不是哥们,我有的选吗?
然后,把题解的式子抄下来了,稍微理解了一部分......
方便起见,记 f ( n , k ) = ∑ i = 0 k C n i f(n,k)=\sum\limits_{i=0}^{k}{C_{n}^{i}} f(n,k)=i=0∑kCni。
f ( n , k ) = ∑ i = 0 k C n i = ∑ i = 0 k C n / p i / p × C n % p i % p = ∑ x = 0 p − 1 C n % p x × ∑ i = 0 k [ i % p = = x ] × C i / p n / p = ∑ x = 0 p − 1 C n % p x × ∑ i = 0 ( k − x ) / p C n / p i = ∑ x = 0 p − 1 C n % p x × f ( n / p , ( k − x ) / p ) f(n,k)=\sum\limits_{i=0}^{k}{C_{n}^{i}}\\ =\sum\limits_{i=0}^{k}{C_{n/p}^{i/p}\times C_{n\%p}^{i\%p}}\\ =\sum\limits_{x=0}^{p-1}{C_{n\%p}^{x}} \times \sum\limits_{i=0}^{k}{[i\%p==x]\times C_{i/p}^{n/p}}\\ =\sum\limits_{x=0}^{p-1}{C_{n\%p}^{x}}\times\sum\limits_{i=0}^{(k-x)/p}{C_{n/p}^{i}}\\ =\sum\limits_{x=0}^{p-1}{C_{n\%p}^{x}\times f(n/p,(k-x)/p)} f(n,k)=i=0∑kCni=i=0∑kCn/pi/p×Cn%pi%p=x=0∑p−1Cn%px×i=0∑k[i%p==x]×Ci/pn/p=x=0∑p−1Cn%px×i=0∑(k−x)/pCn/pi=x=0∑p−1Cn%px×f(n/p,(k−x)/p)
正解
cpp
#include <bits/stdc++.h>
#define int long long
#define mod 2333
using namespace std;
const int N = 2350;
int t;
int c[N][N];
int n, k;
int qpow(int a, int b){
int res = 1;
while (b){
if (b & 1)
res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
int Lucas(int n, int m){
if (n < mod)
return c[n][min(n, m)];
if (m == 0)
return 1;
int x = m % mod, y = n % mod;
int res = c[y][min(x, y)] * Lucas(n / mod, m / mod);
if (m - x){
res = (res + (c[y][y] - c[y][min(x, y)] + mod) % mod * Lucas(n / mod, (m - x - 1) / mod)) % mod;
}
return res;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
for (int i = 0; i < N; i++)
c[i][0] = 1;
for (int i = 1; i < N; i++){
for (int j = 1; j <= i; j++){
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
}
}
for (int i = 0; i < N; i++){
for (int j = 1; j <= i; j++){
c[i][j] = (c[i][j] + c[i][j - 1]) % mod;
}
}
cin >> t;
while (t--){
cin >> n >> k;
cout << Lucas(n, k) << '\n';
}
}
ber,合着前几天我在浪费时间?这又写了 5 道题了,还都是蓝紫......