数论大集合

只要你做完了这道题,除了线性筛和降幂公式以外,所有数论noip知识点就都会了...

题意:求C(n,∑w)*C(∑w,w1)*C(∑w-w1,w2).....mod p(不保证p为质数)

思想:拓展卢卡斯定理

算法:我们可以分别求每个C(n,m),然后乘起来mod p即可

在求每个C(n,m)时,由公式C(n,m)=

于是:C(n,m)==

于是我们仅需求出n!mod p的值

可是首先,由于p不是质数,所以不能线性筛逆元

而且,即使p是质数,由于n的范围过大,筛出来也T了

所以我们要采用一些别的方法:

于是我们可以求出原式模每个的值(或逆元)

然后应用中国剩余定理合并

这就解决了第一个问题

至于第二个问题,我们举例来说明一下:

求19!mod 9的值(经典样例,来自popoqqq)

19!mod 9=19*18*17*16...*1mod 9=(1*2*4*5*7*8*10*11*13*14*16*17*19)mod 9*3^6 mod 9*(1*2*3*4*5*6) mod 9

对于第一部分,显然,1,2,4,5,7,8和10,11,13,14,16,17会构成一个对9的剩余系,那么这堆东西可以用快速幂来做,因为就是一个剩余系

对于第二部分,我们仅需记录一下幂次,然后除掉下面的再处理(别忘了C(n,m)是有除法的,算出来取完模一堆0好像不太妙啊...)

对于第三部分,发现还是一个阶乘,那我们递归处理即可

最后,用中国剩余定理合并,就完事了

代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define ll long long
using namespace std;
ll w[];
ll n,m,p;
ll p0[],pu[],nu[],cnt;
ll ret[];
ll a[];
ll tot=;
struct node
{
ll mi;
ll val;
};
void destroy()
{
int temp=p;
for(int i=;i*i<=temp;i++)
{
if(temp%i==)
{
p0[++cnt]=i;
pu[cnt]=i;
nu[cnt]=;
temp/=i;
while(temp%i==)
{
pu[cnt]*=i;
nu[cnt]++;
temp/=i;
}
}
}
if(temp!=)
{
p0[++cnt]=temp;
pu[cnt]=temp;
nu[cnt]=;
}
}
ll gcd(ll x,ll y)
{
if(y==)
{
return x;
}
return gcd(y,x%y);
}
void ex_gcd(ll a,ll b,ll &x,ll &y)
{
if(b==)
{
x=;
y=;
return;
}
ex_gcd(b,a%b,x,y);
ll t=x;
x=y;
y=t-(a/b)*x;
}
ll get_inv(ll x,ll y)
{
ll xx,yy;
ex_gcd(x,y,xx,yy);
return ((xx%y)+y)%y;
}
ll pow_mul(ll x,ll y,ll mod)
{
ll ans=;
while(y)
{
if(y%)
{
ans*=x;
ans%=mod;
}
x*=x;
x%=mod;
y/=;
}
return ans;
}
node getmul(ll x,ll num)
{
if(x==)
{
node ret;
ret.mi=;
ret.val=;
return ret;
}
ll ans=;
ll p1=x/p0[num],p2=x/pu[num];
if(p2)
{
for(int i=;i<pu[num];i++)
{
if(i%p0[num])
{
ans*=i;
ans%=pu[num];
}
}
ans=pow_mul(ans,p2,pu[num]);
}
for(int i=p2*pu[num]+;i<=x;i++)
{
if(i%p0[num])
{
ans*=i;
ans%=p;
}
}
node re=getmul(p1,num);
node temp;
temp.mi=re.mi+x;
temp.val=ans*re.val%p;
return temp;
}
ll C(ll x,ll y,ll num)//C(x,y)=x!/(y!(x-y)!)
{
if(x<y)
{
return ;
}
node f1=getmul(x,num);
node f2=getmul(y,num);
node f3=getmul(x-y,num);
ll t1=pow_mul(p0[num],f1.mi-f2.mi-f3.mi,pu[num])%pu[num];
ll t2=f1.val*get_inv(f2.val,pu[num])%pu[num];
ll t3=get_inv(f3.val,pu[num])%pu[num];
return t1*t2%pu[num]*t3%pu[num];
}
ll china()
{
ll M=p;
ll ans=;
for(int i=;i<=cnt;i++)
{
ll M0=M/pu[i];
ll xx,yy;
ex_gcd(M0,pu[i],xx,yy);
ans+=xx*M0%p*a[i]%p;
ans%=p;
}
return (ans%M+M)%M;
}
ll solve(ll x,ll y)
{
for(int i=;i<=cnt;i++)
{
a[i]=C(x,y,i);
}
return china();
}
int main()
{
scanf("%lld%lld%lld",&p,&n,&m);
ll s=;
for(int i=;i<=m;i++)
{
scanf("%d",&w[i]);
s+=w[i];
}
if(s>n)
{
printf("Impossible\n");
return ;
}
destroy();
ll re=solve(n,s);
for(int i=;i<=m;i++)
{
re*=solve(s,w[i]);
re%=p;
s-=w[i];
}
printf("%lld\n",re);
return ;
}

bzoj 2142的更多相关文章

  1. BZOJ 2142: 礼物 [Lucas定理]

    2142: 礼物 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1294  Solved: 534[Submit][Status][Discuss] ...

  2. BZOJ 2142 礼物 组合数学 CRT 中国剩余定理

    2142: 礼物 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1450  Solved: 593[Submit][Status][Discuss] ...

  3. bzoj 2142 礼物——扩展lucas模板

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2142 没给P的范围,但说 pi ^ ci<=1e5,一看就是扩展lucas. 学习材料 ...

  4. BZOJ 2142: 礼物

    模非素数下的排列组合,简直凶残 调着调着就过了= = 都不知道怎么过的= = 直接上链接http://hi.baidu.com/aekdycoin/blog/item/147620832b567eb4 ...

  5. BZOJ.2142.礼物(扩展Lucas)

    题目链接 答案就是C(n,m1) * C(n-m1,m2) * C(n-m1-m2,m3)...(mod p) 使用扩展Lucas求解. 一个很简单的优化就是把pi,pi^ki次方存下来,因为每次分解 ...

  6. 【刷题】BZOJ 2142 礼物

    Description 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E 心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多.小E从商店 ...

  7. 「BZOJ 2142」礼物

    题目链接 戳这 Title Solution 这一道题显然可以看出公式为: \[ans=C_{n}^{w_1}*C_{n-w}^{w_2}*...*C_{w_m}^{w_m}\] 然后就可以用扩展Lu ...

  8. bzoj 2142 国家集训队试题 礼物

    问题转化成求C(N,M) mod P p为非素数,那么我们可以将P分解质因数, 也就是 π pi^ci的形式,因为这些pi^ci是互质的,所以我们可以用crt将他们合并 那么问题就转化成了快速求C(N ...

  9. BZOJ - 2142 礼物 (扩展Lucas定理)

    扩展Lucas定理模板题(貌似这玩意也只能出模板题了吧~~本菜鸡见识鄙薄,有待指正) 原理: https://blog.csdn.net/hqddm1253679098/article/details ...

随机推荐

  1. 20190311 Windows上ZooKeeper伪集群的实现

    1. 复制并修改conf/zoo.cfg文件 以zoo1.cfg为例: dataDir=E:\\Develop\\zookeeper\\3.4.6\\zookeeper-3.4.6\\data1 da ...

  2. java8的新特性详解-----------Lamda表达式

    java8最大的亮点就是引入了Lamda表达式  , 函数式编程的概念  具体啥意思我也不知道.只管用就行了,非常的强大,简洁,一个表达式相当于以前的十几行代码  因为之前要实现这种效果全靠if el ...

  3. 内联函数 —— C 中关键字 inline 用法解析

    一.什么是内联函数 在C语言中,如果一些函数被频繁调用,不断地有函数入栈,即函数栈,会造成栈空间或栈内存的大量消耗. 为了解决这个问题,特别的引入了inline修饰符,表示为内联函数. 栈空间就是指放 ...

  4. Spark简介安装和简单例子

    Spark简介安装和简单例子 Spark简介 Spark是一种快速.通用.可扩展的大数据分析引擎,目前,Spark生态系统已经发展成为一个包含多个子项目的集合,其中包含SparkSQL.Spark S ...

  5. java查看当前项目所有线程列表界面【转】

    java查看当前项目所有线程列表界面 1.TestThread(测试类) package com.testdemo.pcis.isc.job.king.panel; public class Test ...

  6. webkitAnimationEnd事件与webkitTransitionEnd事件

    写一个焦点图demo,css3动画完成以后要把它隐藏掉,这里会用到css3的事件,以前没有接触过,结果查了一下发现这是一片新天地啊,而且里面还有好多坑,比如重复动画多次触发什么的.anyway,我还是 ...

  7. Bugly实现app全量更新

    转 http://blog.csdn.net/qq_33689414/article/details/54911895Bugly实现app全量更新 Bugly官网文档 一.参数配置 在app下的gra ...

  8. Qt之QEvent(所有事件的翻译)

    QEvent 类是所有事件类的基类,事件对象包含事件参数. Qt 的主事件循环(QCoreApplication::exec())从事件队列中获取本地窗口系统事件,将它们转化为 QEvents,然后将 ...

  9. 以前的 Delphi版本

                    Delphi 1 Delphi 2 Delphi 3 Delphi 4 Delphi 5 Delphi 6 Delphi 7 Delphi 8 Delphi 2005

  10. FPN-Feature Pyramid Networks for Object Detection

    FPN-Feature Pyramid Networks for Object Detection 标签(空格分隔): 深度学习 目标检测 这次学习的论文是FPN,是关于解决多尺度问题的一篇论文.记录 ...