EXlucas
\(EXLucas\) 扩展卢卡斯定理
·题意
试求:
\]
注意, \(P\) 非质数( :- ) )。
·转化
可以给他进行质因数分解,成为:
\]
x \equiv C^{m}_n ( \mod p_1^{ { \alpha }_1 } ) \\
\dots \\
x \equiv C^{m}_n ( \mod p _ i ^ { { \alpha } _ i } )
\end{cases}\]
然后因为这些后面的模数全都是互质的,所以可以用 \(CRT\) 解决他。
直接拿出随便一个式子,
得到的是
\]
展开得:
\]
但是不能把分母部分直接转逆元,因为你怎么知道 $ gcd( \beta! , p _ i ^ { { \alpha } _ i } ) $
所以你可以定义一个 $ f ( x ) 和 g( x ) $
\(f(x):\) 表示 \(x!\) 中除去所有 \(p\) 剩余的值
\(g(x):\) 表示 \(x!\) 中可以除几个 \(p\)
所以式子变成:
\]
现在求子任务:
\]
可以将能除 \(p\) 的数提出来。
得:
\]
每个地方分一下,得:(写这玩意属实恶心)
\]
最后面的是剩余的。
注意,你的后面是有个取模的,
所以........
\]
由于这是\(n!\),我们想要 \(f(n)\)
首先的,\(f(n)\) 中 肯定没有 \(p\) , 那么将有 \(p\) 的全提出来, (注意,\(\left\lfloor \frac{ n }{ p } \right\rfloor ! 可能含有\))
再浅浅的变一下形:
\]
那么 $f( n ) $ 就是将所有含 \(p\) 的式子择出去 (烦恼丢出去)
得:
\]
同时我们也可以得到:
\]
这个可以通过择出去得 \(p\) 得知。
· \(Code\)
\]
点击查看代码
#include<bits/stdc++.h>
using namespace std ;
#define int long long
const int N = 1000010 ;
int prime_num[ N ] , prime[ N ] , tot ;
int bemod[ N ] , relive[ N ] ;
inline int read( )
{
int x = 0 , f = 1 ;
char c = getchar( ) ;
while ( c > '9' || c < '0' )
{
if( c == '-' )
{
f = -f ;
}
c = getchar( ) ;
}
while ( c >= '0' && c <= '9' )
{
x = x * 10 + c - '0' ;
c = getchar( ) ;
}
return x * f ;
}
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 Original , int mo )
{
int x , y ;
exgcd( Original , mo , x , y ) ;
return ( x + mo ) % mo ;
}
void decompose( int mod )
{
int tmp = mod ;
for ( int i = 2 ; i <= sqrt( mod ) ; ++ i )
{
if( tmp % i == 0 )
{
prime[ ++ tot ] = i ;
while( tmp % i == 0 )
{
tmp /= i ;
prime_num[ tot ] ++ ;
}
}
}
if( tmp != 1 )
{
prime[ ++ tot ] = tmp ;
prime_num[ tot ] ++ ;
}
return ;
}
int g( int n , int p )
{
if( n < p )
{
return 0 ;
}
return ( n / p ) + g( n / p , p ) ;
}
inline int Quick_Pow( int a , int b , int c )
{
int ans = 1 ;
a %= c ;
while ( b > 0 )
{
if( b & 1 ) ans = ( ans * a ) % c ;
b >>= 1 ;
a = ( a * a ) % c ;
}
return ans ;
}
inline int Regular_Quick_Pow( int a , int b )
{
int ans = 1 ;
while ( b > 0 )
{
if( b & 1 ) ans *= a ;
b >>= 1 ;
a *= a ;
}
return ans ;
}
int f( int n , int p , int kala )
{
if( !n ) return 1 ;
int res = 1 , vim = 1 ;
// int kala = Regular_Quick_Pow( p , k ) ;
// cout << kala << '\n' ;
// if( n >= kala )
// {
for ( int i = 1 ; i <= kala ; ++ i )
{
if( i % p != 0 )
{
res = ( res * i ) % kala ;
}
}
// }
int up = n / kala ;
res = Quick_Pow( res , up , kala ) ;
for( int i = kala * ( n / kala ) ; i <= n ; ++ i )
{
if( i % p != 0 ) vim = ( vim * ( i % kala ) ) % kala ;
}
int returning = ( ( ( ( f( n / p , p , kala ) * vim ) % kala ) * res ) % kala ) ;
// cout << returning << '\n' ;
return returning ;
}
int EXCRT( int r[ ] , int mo[ ] , int n )
{
int m1 , m2 , r1 , r2 , p , q ;
m1 = mo[ 1 ] , r1 = r[ 1 ] ;
for( int i = 2 ; i <= n ; ++ i )
{
int x , y ;
m2 = mo[ i ] , r2 = r[ i ] ;
int d = exgcd( m1 , m2 , x , y ) ;
//cout << d << '\n' ;
if( ( r2 - r1 ) % d != 0 ) return -1 ;
x = x * ( r2 - r1 ) / d ;
int delta = m2 / d ;
x = ( x % delta + delta ) % delta ;
r1 = m1 * x + r1 ;
m1 = m1 * delta ;
}
return ( r1 % m1 + m1 ) % m1 ;
}
int n , m , mod , ksum ;
void get_fge( int now , int num , int i )
{
int kala = Regular_Quick_Pow( now , num ) ;
int C1 = f( n , now , kala ) ;
int C2 = f( m , now , kala ) ;
int C3 = f( n - m , now , kala ) ;
int G1 = g( n , now ) , G2 = g( m , now ) , G3 = g( n - m , now ) ;
bemod[ i ] = ( ( ( ( ( C1 * inv( C2 , kala ) ) % kala ) * inv( C3 , kala ) % kala ) % kala ) * ( Quick_Pow( now , G1 - G2 - G3 , kala ) ) % kala ) % kala ;
relive[ i ] = kala ;
}
signed main( )
{
#ifndef ONLINE_JUDGE
freopen( "1.in" , "r" , stdin ) ;
freopen( "1.out", "w" , stdout ) ;
#endif
// 扩展卢卡斯板子 -> C( n , m ) mod ( p ∈ N * )
cin >> n >> m >> mod ;
// decompose( mod ) ;
int tmp = mod ;
for ( int i = 2 ; i <= sqrt( mod ) ; ++ i )
{
if( tmp % i == 0 )
{
prime[ ++ tot ] = i ;
while( tmp % i == 0 )
{
tmp /= i ;
prime_num[ tot ] ++ ;
}
get_fge( prime[ tot ] , prime_num[ tot ] , tot ) ;
}
}
if( tmp != 1 )
{
prime[ ++ tot ] = tmp ;
prime_num[ tot ] ++ ;
get_fge( prime[ tot ] , prime_num[ tot ] , tot ) ;
}
int ans = 0 ;
for ( int i = 1 ; i <= tot ; ++ i )
{
int mer = mod / relive[ i ] ;
int invmer = inv( mer , relive[ i ] ) ;
ans = ( ans + ( mer * ( invmer * bemod[ i ] ) % mod ) % mod ) % mod ;
}
cout << ans ;
}
结尾撒花 \(\color{pink}✿✿ヽ(°▽°)ノ✿\)
EXlucas的更多相关文章
- bzoj3129[Sdoi2013]方程 exlucas+容斥原理
3129: [Sdoi2013]方程 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 582 Solved: 338[Submit][Status][ ...
- CRT and exlucas
CRT 解同余方程,形如\(x \equiv c_i \ mod \ m_i\),我们对每个方程构造一个解满足: 对于第\(i\)个方程:\(x \equiv 1 \ mod \ m_i\),\(x ...
- Luogu2183 礼物 ExLucas、CRT
传送门 证明自己学过exLucas 这题计算的是本质不相同的排列数量,不难得到答案是\(\frac{n!}{\prod\limits_{i=1}^m w_i! \times (n - \sum\lim ...
- exLucas学习笔记
exLucas学习笔记 Tags:数学 写下抛硬币和超能粒子炮改 洛谷模板代码如下 #include<iostream> #define ll long long using namesp ...
- 扩展卢卡斯定理(Exlucas)
题目链接 戳我 前置知识 中国剩余定理(crt)或扩展中国剩余定理(excrt) 乘法逆元 组合数的基本运用 扩展欧几里得(exgcd) 说实话Lucas真的和这个没有什么太大的关系,但是Lucas还 ...
- 【知识总结】扩展卢卡斯定理(exLucas)
扩展卢卡斯定理用于求如下式子(其中\(p\)不一定是质数): \[C_n^m\ mod\ p\] 我们将这个问题由总体到局部地分为三个层次解决. 层次一:原问题 首先对\(p\)进行质因数分解: \[ ...
- Algorithm: CRT、EX-CRT & Lucas、Ex-Lucas
中国剩余定理 中国剩余定理,Chinese Remainder Theorem,又称孙子定理,给出了一元线性同余方程组的有解判定条件,并用构造法给出了通解的具体形式. \[ \begin{aligne ...
- exlucas易错反思
模板和题解 复习了一下 exlucas的模板,结果写挂四次(都没脸说自己以前写过 是该好好反思一下呢~ 错的原因如下: 第一次WA:求阶乘的时候忘了递归处理(n/p)! 第二次WA:求阶乘时把p当成循 ...
- 模板:exlucas
求$C_n^m mod p$,其中p不是质数且不保证p能分解为几个不同质数的乘积(也就是不能用crt合并) #include<iostream> #include<cstdio> ...
- 洛谷$P$3301 $[SDOI2013]$方程 $exLucas$+容斥
正解:$exLucas$+容斥 解题报告: 传送门! 在做了一定的容斥的题之后再看到这种题自然而然就应该想到容斥,,,? 没错这题确实就是容斥,和这题有点儿像 注意下的是这里的大于和小于条件处理方式不 ...
随机推荐
- Android/SELinux 添加 AVC 权限
Android/SELinux 添加 AVC 权限 背景 在Android应用层中编写c/c++应用时,发现接口调用出现问题,logcat才知道是因为:权限不够. type=1400 audit(0. ...
- Linux设备模型:4、sysfs
作者:wowo 发布于:2014-3-14 18:31 分类:统一设备模型 http://www.wowotech.net/device_model/dm_sysfs.html 前言 sysfs是一个 ...
- GUI测试还能这么玩(Page Code Gen + Data Gen + Headless)
标签(空格分隔): GUI测试还能这么玩(Page Code Gen + Data Gen + Headless) 页面对象自动生成 在前面的文章中,我已经介绍过页面对象(Page Object)模型 ...
- node.js 手稿
- IDEA 设置自动去掉不用的import
- JavaSe 统计字符串中字符出现的次数
public static void main(String[] args) { // 1.字符串 String str = "*Constructs a new <tt>Has ...
- vuex使用和场景案例
vuex是vue提供的一个集中式状态管理器,用于对数据的集中式管理. vuex有四个重要的属性:state.mutations.actions.getters 1.vuex的使用 安装 npm ins ...
- Django model 层之Models与Mysql数据库小结
Django model 层之Models与Mysql数据库小结 by:授客 QQ:1033553122 测试环境: Python版本:python-3.4.0.amd64 下载地址:https:// ...
- 蓝图中如何存储树结构: NPC对话的打开方式
BFS来扩展成数组, 然后每一个node节点的child存储为索引.
- M1 Mac安装anaconda3
1.正常安装 首先进入官网https://www.anaconda.com/ 下载,安装 自行大胆的安装 2.环境配置 直接安装完成后,代码文件的存储路径为默认路径,为了更好的管理代码文件我们需要更换 ...