这道题是求组合数终极版.

C(n,m) mod P

n>=1e9 m>=1e9 P>=1e9且为合数且piqi<=1e5

拓展lucas定理.

实际上就是一点数论小知识的应用.

这篇文章对于CRT和lucas定理的学习非常不错.

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define FILE "dealing"
#define up(i,j,n) for(int i=j;i<=n;i++)
#define db double
#define pii pair<ll,ll>
#define pb push_back
template<class T> inline bool cmin(T& a,T b){return a>b?a=b,true:false;}
template<class T> inline bool cmax(T& a,T b){return a<b?a=b,true:false;}
template<class T> inline T squ(T a){return a*a;}
const int maxn=+,inf=1e9+;
ll read(){
ll x=,f=,ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<='')x=(x<<)+(x<<)+ch-'',ch=getchar();
return x*f;
}
ll n,m,mod,w[maxn];
struct node{
ll p,a,num;
}a[maxn];int tot=;
void divide(ll n){
for(ll i=;i*i<=n;i++){
if(n%i==){
n/=i;
a[++tot].p=i,a[tot].a=,a[tot].num=i;
while(n%i==){
a[tot].a++;
a[tot].num*=i;
n/=i;
}
}
if(n==)break;
}
if(n!=)a[++tot].p=n,a[tot].num=n,a[tot].a=;
}
ll qpow(ll a,ll b,ll mod){
ll ans=;
for(;b;b>>=,a=a*a%mod)
if(b&)ans=ans*a%mod;
return ans;
}
pii deal(ll n,int pos){
pii t;t.first=,t.second=;
if(n==)return t;
ll mod=a[pos].num,p=a[pos].p;
for(int i=;i<mod;i++)
if(i%p)t.first=t.first*i%mod;
t.first=qpow(t.first,n/mod,mod);
for(int i=;i<=n%mod;i++)if(i%p)t.first=t.first*i%mod;
t.second+=n/p;
pii w=deal(n/p,pos);
t.first=t.first*w.first%mod;
t.second+=w.second;
return t;
}
ll A[maxn],M[maxn],Ans=;
void exgcd(ll a,ll b,ll& d,ll& x,ll& y){
if(b==){d=a;x=,y=;return;}
exgcd(b,a%b,d,x,y);
ll t=x;
x=y;
y=t-a/b*x;
}
void CRT(){
ll AA=A[],MM=M[];
for(int i=;i<=tot;i++){
ll d,k,x,y;
exgcd(MM,M[i],d,x,y);
x*=(A[i]-AA);
x=(x%M[i]+M[i])%M[i];
AA=(AA+x*MM)%(MM*M[i]);
MM=MM*M[i];
}
printf("%lld\n",AA);
}
int main(){
//freopen(FILE".in","r",stdin);
//freopen(FILE".out","w",stdout);
mod=read(),n=read(),m=read();
ll sum=;
up(i,,m)w[i]=read(),sum+=w[i];
if(sum<n)w[++m]=n-sum;
else if(sum>n){
printf("Impossible\n");
return ;
}
divide(mod);
for(int i=;i<=tot;i++){
ll mod=a[i].num,p=a[i].p;
pii t=deal(n,i);
for(int j=;j<=m;j++){
pii k=deal(w[j],i);
t.second-=k.second;
ll x,y,d;
exgcd(k.first,mod,d,x,y);
x=(x%mod+mod)%mod;
t.first=t.first*x%mod;
}
A[i]=t.first*qpow(p,t.second,mod)%mod,M[i]=mod;
}
CRT();
return ;
}

最新文章

  1. IOS开发基础知识--碎片3
  2. Xcode 此证书签发者无效
  3. MyBatis简介
  4. IT之人生感悟
  5. IntelliJ和tomcat中的目录结构
  6. PostgreSQL Replication之第十二章 与Postgres-XC一起工作(5)
  7. mybatis sql注入安全
  8. CSS开启硬件加速 hardware accelerated
  9. java分布式开发,什么是分布式开发
  10. Spark集群搭建_YARN
  11. android studio 转为eclipse快捷键后还存在的问题汇总
  12. Java工程师成神之路思维导图
  13. 异常值处理outlier
  14. Xcode 中armv6 armv7 armv7s arm64 i386 x86_64 归纳 (Architectures, Valid Architectures, Build Active Architecture Only)
  15. boost Asio网络编程简介
  16. java基本类型的默认值
  17. Oracle EBS 贷项通知单核销
  18. 网络协议-网络分层、TCP/UDP、TCP三次握手和四次挥手
  19. print 不换行
  20. 从 exe.config 读取appSettings 中的配置数据

热门文章

  1. EasyMvc入门教程-基本控件说明(7)文字块导航
  2. (转)ubuntu/var/log/下各个日志文件
  3. ElasticSearch命令增加字段总结
  4. 【LeetCode-面试算法经典-Java实现】【139-Word Break(单词拆分)】
  5. same-tree——比较两个二叉树是否相同
  6. Git 学习之--安装配置GitHub
  7. 使用 mybatis + flying + 双向相关建模 的电商后端
  8. winform 下载文件显示进度和百分比
  9. 转jmeter 性能测试 JDBC Request (查询数据库获取数据库数据) 的使用
  10. 高性能HTTP加速器Varnish安装与配置(包含常见错误)