组合计算的性质:

C(n,m)= m! / (n!(m-n)!)

C(n,m)=C(m-n,m); C(n,m)=C(n,m-1)+C(n-1,m-1);

二项式定理:(a+b)^n=sigema(k=0~n) C(k,n)*a^k*b^(n-k)

lucas定理:C(n,m)≡C(n%p,m%p)*C(n/p,m/p)  (mod p)

catalan数: Cat(n)=C(n,2n)/n+1  Cat(n)=Cat(n-1)*(4n-2)/(n+1)

计算系数 通过二项式定理变形其实就是求C(n,k)*a^n*b^m,用下逆元

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL mod=; LL quick_pow(LL A,LL p)
{
int ret=;
while(p!=)
{
if(p%==)ret=(ret*A)%mod;
A=(A*A)%mod;p/=;
}
return ret;
}
LL jiecheng(LL k)
{
LL ret=;
for(int i=;i<=k;i++)ret=(ret*i)%mod;
return ret;
}
LL getniyuan(LL k)
{
return quick_pow(k,mod-);
} int main()
{
LL a,b,k,n,m;
scanf("%lld%lld%lld%lld%lld",&a,&b,&k,&n,&m);
LL ans=( (jiecheng(k)*getniyuan( jiecheng(n)*jiecheng(k-n)%mod )%mod) *
(quick_pow(a,n)*quick_pow(b,m)%mod) )%mod;
printf("%lld\n",ans);
return ;
}

计算系数

Counting Swaps 神仙题,%lyd吧。。。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL mod=1e9+; LL quick_pow(LL A,LL p)
{
int ret=;
while(p!=)
{
if(p%==)ret=(ret*A)%mod;
A=(A*A)%mod;p/=;
}
return ret;
}
LL jiecheng(LL k)
{
LL ret=;
for(int i=;i<=k;i++)ret=(ret*i)%mod;
return ret;
}
LL getniyuan(LL k)
{
return quick_pow(k,mod-);
} int nxt[];
bool v[];
LL dfs(int x,int d)
{
if(v[x]==true)return d;
v[x]=true;
dfs(nxt[x],d+);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&nxt[i]); LL tot=,ans=,cnt;cnt=n;
memset(v,false,sizeof(v));
for(int i=;i<=n;i++)
{
if(v[i]==false)
{
int L=dfs(i,);
if(L>)
{
tot++;
ans=(ans*quick_pow(L,L-)%mod)*getniyuan(jiecheng(L-))%mod;
}
else cnt--;
}
}
if(tot==)printf("1\n");
else
{
ans=ans*jiecheng(cnt-tot)%mod;
printf("%lld\n",ans);
}
}
return ;
}

Count Swaps

bzoj1951 由欧拉定理的推论,变成计算sigema(d|n)C(d,n)%(mod-1),这个用卢卡斯定理搞,但是mod不是质数,那么分解分别搞,然后得到4个同余方程,解出就是指数了,最后快速幂即可。

upd:感觉之前的阶乘模数有点假。。但是应该是对的

快速幂+crt并没有exgcd优秀的说。。。卡了一波常数才过的。。。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL mod=;
const LL md[]={,,,}; int quick_pow(int A,int p,int mod)
{
int ret=;
while(p!=)
{
if(p%==)ret=(LL)ret*A%mod;
A=(LL)A*A%mod;p/=;
}
return ret;
}
LL fac[][],fac_inv[][];
void initC()
{
for(int j=;j<=;j++)fac[j][]=,fac_inv[j][]=;
for(int i=;i<=md[];i++)
for(int j=;j<=;j++)
fac[j][i]=fac[j][i-]*i%md[j],fac_inv[j][i]=quick_pow(fac[j][i],md[j]-,md[j]);
}
LL getC(LL n,LL m,LL p){return fac[p][n]*fac_inv[p][m]%md[p]*fac_inv[p][n-m]%md[p];}
LL lucas(LL n,LL m,LL p)
{
LL ans=;
while(m>)
{
LL a=n%md[p],b=m%md[p];
if(a<b)return ;
ans=ans*getC(a,b,p)%md[p];
n/=md[p],m/=md[p];
}
return ans;
} LL a[];
LL solve(LL n,LL k)
{
for(int i=;i<=;i++)a[i]=lucas(n,k,i);
LL M=mod-,x=;
for(int i=;i<=;i++)//crt
x=(x+a[i]*(M/md[i])*quick_pow(M/md[i],md[i]-,md[i]))%(mod-);
return x;
} int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
initC();
int n,G,p=;
scanf("%d%d",&n,&G);
if(G==mod){printf("0\n");return ;}
for(int i=;i*i<=n;i++)
if(n%i==)
{
p=(p+solve(n,i))%(mod-);
if(i*i!=n)p=(p+solve(n,n/i))%(mod-);
}
printf("%d\n",quick_pow(G,p,mod));
return ;
}

bzoj1951(upd)

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const LL mod=;
const LL md[]={,,,}; LL exgcd(LL a,LL b,LL &x,LL &y)
{
if(a==)
{
x=;y=;
return b;
}
else
{
LL tx,ty;
LL d=exgcd(b%a,a,tx,ty);
x=ty-b/a*tx;
y=tx;
return d;
}
}
LL quick_pow(LL A,LL p)
{
LL ret=;
while(p!=)
{
if(p%==)ret=(ret*A)%mod;
A=(A*A)%mod;p/=;
}
return ret;
}
LL inv(LL a,LL p)
{
LL x,y;
LL d=exgcd(a,p,x,y);
return (x%p+p)%p;
} //--------------------------------------------------- LL jc[];
LL lucas(LL N,LL M,LL p)
{
LL ans=;
while(M>)
{
LL a=N%p,b=M%p;
if(a>b)return ; ans=ans*jc[b]%p;
ans=ans*inv(jc[a],p)%p;
ans=ans*inv(jc[b-a],p)%p; N/=p;M/=p;
}
return ans;
}//lucas
LL g[];
void getzs(LL n)
{
jc[]=;
for(int i=;i<=md[];i++)jc[i]=(jc[i-]*i)%(mod-); for(int i=;i*i<=n;i++)
{
if(n%i==)
{
for(int j=;j<=;j++)
g[j]=(g[j]+lucas(i,n,md[j]))%md[j];
if(i!=n/i)
{
for(int j=;j<=;j++)
g[j]=(g[j]+lucas(n/i,n,md[j]))%md[j];
}
}
}
} //--------------------------------------------------- LL u1,v1,u2,v2;
void merge()
{
LL A=u1,B=u2,K=v2-v1,x,y;
LL d=exgcd(A,B,x,y); x=(x*(K/d)%(B/d)+(B/d))%(B/d);
v1=u1*x+v1;
u1=u1/d*u2;
}
LL solve()
{
u1=md[],v1=g[];
for(int i=;i<=;i++)
u2=md[i], v2=g[i], merge();
return v1;
} int main()
{
LL n,g;
scanf("%lld%lld",&n,&g);g%=mod;
if(g==){printf("0\n");return ;} getzs(n);
LL p=solve();
printf("%lld\n",quick_pow(g,p));
return ;
}

bzoj1951

0x36 组合计数的更多相关文章

  1. 算法竞赛进阶指南0x36组合计数

    概述 AcWing211. 计算系数 #include <bits/stdc++.h> using namespace std; const int mod = 10007 ; int k ...

  2. bzoj 2281 [Sdoi2011]黑白棋(博弈+组合计数)

    黑白棋(game) [问题描述] 小A和小B又想到了一个新的游戏. 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色. 最左边是白色棋子,最右边是黑色棋子,相邻的棋子颜色 ...

  3. BZOJ 4555: [Tjoi2016&Heoi2016]求和 [分治FFT 组合计数 | 多项式求逆]

    4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...

  4. BZOJ 4555: [Tjoi2016&Heoi2016]求和 [FFT 组合计数 容斥原理]

    4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...

  5. 【BZOJ5491】[HNOI2019]多边形(模拟,组合计数)

    [HNOI2019]多边形(模拟,组合计数) 题面 洛谷 题解 突然特别想骂人,本来我考场现切了的,结果WA了几个点,刚刚拿代码一看有个地方忘记取模了. 首先发现终止态一定是所有点都向\(n\)连边( ...

  6. [总结]数论和组合计数类数学相关(定理&证明&板子)

    0 写在前面 0.0 前言 由于我太菜了,导致一些东西一学就忘,特开此文来记录下最让我头痛的数学相关问题. 一些引用的文字都注释了原文链接,若侵犯了您的权益,敬请告知:若文章中出现错误,也烦请告知. ...

  7. 【BZOJ5323】[JXOI2018]游戏(组合计数,线性筛)

    [BZOJ5323][JXOI2018]游戏(组合计数,线性筛) 题面 BZOJ 洛谷 题解 显然要考虑的位置只有那些在\([l,r]\)中不存在任意一个约数的数. 假设这样的数有\(x\)个,那么剩 ...

  8. 【BZOJ5305】[HAOI2018]苹果树(组合计数)

    [BZOJ5305][HAOI2018]苹果树(组合计数) 题面 BZOJ 洛谷 题解 考虑对于每条边计算贡献.每条边的贡献是\(size*(n-size)\). 对于某个点\(u\),如果它有一棵大 ...

  9. 【BZOJ3142】[HNOI2013]数列(组合计数)

    [BZOJ3142][HNOI2013]数列(组合计数) 题面 BZOJ 洛谷 题解 唯一考虑的就是把一段值给分配给\(k-1\)天,假设这\(k-1\)天分配好了,第\(i\)天是\(a_i\),假 ...

随机推荐

  1. SwiftUI 官方教程

    SwiftUI 官方教程 完整中文教程及代码请查看 https://github.com/WillieWangWei/SwiftUI-Tutorials   SwiftUI 官方教程 SwiftUI ...

  2. 适配器模式(adapter)C++实现

    意图:将一个类的接口转换成客户希望的另一个接口. 适用性:1.你想使用一个已存在的类,而它的接口不符合你的需求. 2.你想创建一个可以复用的类,该类可以与其它不相关的类或不可预见的类协同工作. 类适配 ...

  3. Python 之 基础知识(四)

    一.公共方法(列表.元组.字典以及字符串) 1.内置函数 cmp函数取消可以用比较运算符来代替,但是字典是无序的,故而不可以用比较运算符比较. 2.切片(列表.元组.字符串适用) 3.运算符 列表中直 ...

  4. Qt5.2 for Android 配置及部署到手机运行

    使用DNK编程也没有那么难,使用QT为安卓跨平台编程需要安装NDK,SDK通过NDK调用C++程序,偶尔能提高一些效率. SDK下载地址:http://developer.android.com/sd ...

  5. 采用requests库构建简单的网络爬虫

    Date: 2019-06-09 Author: Sun 我们分析格言网 https://www.geyanw.com/, 通过requests网络库和bs4解析库进行爬取此网站内容. ​ 项目操作步 ...

  6. URLLib库使用

    Date: 2019-06-19 Author: Sun urllib ​ 在Python 3以后的版本中,urllib2这个模块已经不单独存在(也就是说当你import urllib2时,系统提示你 ...

  7. 基于fullpage的自动播放,手动播放,暂停页面的功能

    功能如下: 1.默认加载方式为“自动播放 ”方式,即从第1屏至第5屏 页面循环加载显示,每屏每次仅显示1个页面,页面间停留时间为“10”秒2.手动播放过程中,按数字键“1”-“5”,将直接切到指定页面 ...

  8. Python数据分析4------------数据变换

    1.简单变换: 开方.平方.对数等 2.数据规范化: (1)离差标准化(最小最大标准化):消除量纲(单位)影响以及变异大小因素的影响. x1=(x-min)/(max-min) 代码:data1=(d ...

  9. sublime Text3的使用

    sublime text百度百科: Sublime Text 是一个代码编辑器,也是HTML和散文先进的文本编辑器.Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python ...

  10. Project Euler 24 Lexicographic permutations( 康拓逆展开 )

    题意: 排列指的是将一组物体进行有顺序的放置.例如,3124是数字1.2.3.4的一个排列.如果把所有排列按照数字大小或字母先后进行排序,我们称之为字典序排列.0.1.2的字典序排列是:012 021 ...