博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
codeforces2015ICL,Finals,Div.1#J Ceizenpok’s formula 扩展Lucas定理 扩展CRT
阅读量:5268 次
发布时间:2019-06-14

本文共 2950 字,大约阅读时间需要 9 分钟。

默默敲了一个下午,终于过了,

 

扩展Lucas是什么,就是对于模数p,p不是质数,但是不大,如果是1e9这种大数,可能没办法,

对于1000000之内的数是可以轻松解决的。

 

 

代码完全手写,直接写了扩展的中国剩余定理(普通的不会写)

题意:给你n,m,p 求C(n,m)%p

1 #include
2 #include
3 #include
4 #include
5 #include
6 7 #define ll long long 8 #define N 27 9 using namespace std; 10 inline ll read() 11 { 12 ll x=0,f=1;char ch=getchar(); 13 while(!isdigit(ch)){
if(ch=='-')f=-1;ch=getchar();} 14 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 15 return x*f; 16 } 17 18 ll n,m,p,ans,Modulo; 19 ll prime[N],num[N],mod[N]; 20 int tot; 21 22 void get_factor(ll p) 23 { 24 int up=(int)sqrt(p); 25 for (int i=2;i<=up;i++) 26 { 27 if (p%i==0) 28 { 29 prime[++tot]=i,mod[tot]=1; 30 while(p%i==0) 31 { 32 p/=i; 33 num[tot]++; 34 mod[tot]*=i; 35 } 36 } 37 } 38 if (p>1) num[++tot]=1,prime[tot]=mod[tot]=p; 39 } 40 ll fast_pow(ll a,ll b,ll mod) 41 { 42 ll ans=1; 43 while(b) 44 { 45 if (b&1) (ans*=a)%=mod; 46 (a*=a)%=mod; 47 b>>=1; 48 } 49 return ans; 50 } 51 ll Recursion(ll n,ll x) 52 { 53 if (!n) return 1; 54 ll dw=1; 55 for (ll i=1;i<=mod[x];i++) 56 if (i%prime[x]!=0) (dw*=i)%=mod[x]; 57 ll res=fast_pow(dw,n/mod[x],mod[x]); 58 for (ll i=n/mod[x]*mod[x]+1;i<=n;i++) 59 if (i%prime[x]!=0) (res*=i%mod[x])%=mod[x]; 60 return (res*Recursion(n/prime[x],x))%mod[x]; 61 } 62 void Ex_gcd(ll a,ll b,ll &x,ll &y) 63 { 64 if (!b) 65 { 66 x=1,y=0; 67 return; 68 } 69 else 70 { 71 Ex_gcd(b,a%b,x,y); 72 ll t=x;x=y;y=t-a/b*y; 73 } 74 } 75 ll Inv(ll a,ll b) 76 { 77 ll x,y; 78 Ex_gcd(a,b,x,y); 79 if (x<0) x+=b; 80 return x; 81 } 82 ll get_combination(ll x) 83 { 84 ll ans=Recursion(n,x),k=0; 85 for (ll i=n;i;i/=prime[x]) k+=i/prime[x]; 86 for (ll i=m;i;i/=prime[x]) k-=i/prime[x]; 87 for (ll i=n-m;i;i/=prime[x]) k-=i/prime[x]; 88 ans*=fast_pow(prime[x],k,mod[x]); 89 ans%=mod[x]; 90 ll res1=Recursion(m,x),res2=Recursion(n-m,x); 91 ans*=Inv(res1,mod[x]),ans%=mod[x]; 92 ans*=Inv(res2,mod[x]),ans%=mod[x]; 93 return ans; 94 } 95 void combine(ll &a,ll &b,ll c,ll d) 96 { 97 ll inv=Inv(b,d)*(c-a)%d; 98 a=inv*b+a,b=b*d,a%=b; 99 }100 int main()101 {102 freopen("fzy.in","r",stdin);103 freopen("fzy.out","w",stdout);104 105 n=read(),m=read(),p=read();106 get_factor(p);107 ans=get_combination(1),Modulo=mod[1];108 for (int i=2;i<=tot;i++)109 {110 ll res=get_combination(i),new_mod=mod[i];111 combine(ans,Modulo,res,new_mod);112 }113 printf("%lld\n",(ans%Modulo+Modulo)%Modulo);114 }

 

转载于:https://www.cnblogs.com/fengzhiyuan/p/8631704.html

你可能感兴趣的文章
android:scaleType属性
查看>>
mysql-5.7 innodb 的并行任务调度详解
查看>>
shell脚本
查看>>
Upload Image to .NET Core 2.1 API
查看>>
Js时间处理
查看>>
【雷电】源代码分析(二)-- 进入游戏攻击
查看>>
Entityframework:“System.Data.Entity.Internal.AppConfig”的类型初始值设定项引发异常。...
查看>>
Linux中防火墙centos
查看>>
如何设置映射网络驱动器的具体步骤和方法
查看>>
283. Move Zeroes把零放在最后面
查看>>
centos下同时启动多个tomcat
查看>>
slab分配器
查看>>
【读书笔记】C#高级编程 第三章 对象和类型
查看>>
【SVM】libsvm-python
查看>>
Jmeter接口压力测试,Java.net.BindException: Address already in use: connect
查看>>
Leetcode Balanced Binary Tree
查看>>
go:channel(未完)
查看>>
[JS]递归对象或数组
查看>>
多线程《三》进程与线程的区别
查看>>
linux sed命令
查看>>