CF896D
CF896D
说一下感觉有用的点:
1.对卡特兰数敏感一些,就是一些加减的操作,要保证每时每刻都为正。
2.对于组合数取模,模数非质数。
设模数为 ,将模数分解质因数,即: , 即模数的质因数个数。
对于组合数中阶乘的取模,预处理, 枚举要乘的数,记为 。
将 分解成 的形式,这里的 是模数的质因子,可以发现 与 互质,根据欧拉定理:当 时 ,用快速幂可以求出 关于 的逆元。
之后做一下分解数 的质因子的前缀和,因为只涉及到乘和除的操作,相当于是将这个数乘这些质因子再乘回去。
Code moo~~
using namespace std; #define int long long #define re register int #define pc_ putchar(' ') #define pc_n putchar('\n') #define Bessie signed const int CTR = 2e5 + 7; int n, MOD, l, r; int phi; int qpow(int x, int y) { int base = 1; while(y) { if(y & 1) base = base * x % MOD; x = x * x % MOD; y >>= 1; } return base; } int p[CTR], cnt; int zs[CTR][40]; int jc[CTR], inv[CTR]; void init() { int res = MOD; for(re i = 2; i * i <= res; ++i) { if(res % i) continue; p[++cnt] = i; while(!(res % i)) res /= i; } if(res != 1) p[++cnt] = res; jc[0] = inv[0] = jc[1] = inv[1] = 1; for(re i = 2, res; i <= n; ++i) { res = i; for(re j = 1; j <= cnt; ++j) { zs[i][j] = zs[i - 1][j]; while(!(res % p[j])) { res /= p[j]; ++zs[i][j]; } } jc[i] = jc[i - 1] * res % MOD; inv[i] = qpow(jc[i], phi - 1); } } int C(int n, int m) { if(n < m) return 0; if(m == 0) return 1; int res = jc[n] * inv[m] % MOD * inv[n - m] % MOD; for(re i = 1; i <= cnt; ++i) (res *= qpow(p[i], zs[n][i] - zs[n - m][i] - zs[m][i])) %= MOD; return res; } int ans; Bessie main() { n = read(), MOD = read(), l = read(), r = read(); int res = MOD; phi = MOD; for(re i = 2; i * i <= MOD; ++i) { if(res % i) continue; phi = phi / i * (i - 1); while(!(res % i)) res /= i; } if(res != 1) phi = phi / res * (res - 1); init(); for(re i = 0; i <= n; ++i) (ans += C(n, i) * ((C(i, ceil((double)(i + l) / 2))) - C(i, (i + r) / 2 + 1) % MOD + MOD) % MOD) %= MOD; ot(ans); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】