hihocoder1639 图书馆 [数学]
已知数组a[]及其和sum, 求sum! / (a1!a2!...an!) 的个位数的值。
求某数的逆元表写成了求某数阶乘的逆元表,故一直没找到错误。
P 是质数的幂
B 表示质数,P 表示模数,cal(n) 将返回 n!,以 a × B^b 形式表示,a为模P的情况下。
ll n,x,y,P,B,s[];
ll exgcd(ll a,ll b){
if(!b)return x=,y=,a;
ll d=exgcd(b,a%b),t=x;
return x=y,y=t-a/b*y,d;
}
ll rev(ll a,ll P){exgcd(a,P);while(x<)x+=P;return x%P;}
ll pow(ll a,ll b,ll P){ll t=;for(;b;b>>=1LL,a=a*a%P)if(b&1LL)t=t*a%P;return t;}
struct Num{
ll a,b;
Num(ll a = , ll b = ): a(a), b(b){}
Num operator*(Num x){return Num(a*x.a%P, b+x.b);}
Num operator/(Num x){return Num(a*rev(x.a,P)%P, b-x.b);}
};
Num cal(ll n){return n? Num(s[n%P]*pow(s[P],n/P,P)%P,n/B)*cal(n/B): Num();}
void pre(){
for(int i = s[] = ; i < P; i++)
if(i%B) s[i]=s[i-]*i%P;
else s[i] = s[i-];
s[P] = s[P-];
}
int main(){
B = , P = , pre();
cal(n);
}
自己的题解如下:
#include <bits/stdc++.h> #define ll long long
#define ull unsigned long long
#define st first
#define nd second
#define pii pair<int, int>
#define pil pair<int, ll>
#define pli pair<ll, int>
#define pll pair<ll, ll>
#define tiii tuple<int, int, int>
#define pw(x) ((1LL)<<(x))
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define sqr(x) ((x)*(x))
#define SIZE(A) ((int)(A.size()))
#define LENGTH(A) ((int)(A.length()))
#define FIN freopen("A.in","r",stdin);
#define FOUT freopen("A.out","w",stdout);
using namespace std;
/***********/
template<typename T>
bool scan (T &ret) {
char c;
int sgn;
if (c = getchar(), c == EOF) return ; //EOF
while (c != '-' && (c < '' || c > '') ) c = getchar();
sgn = (c == '-') ? - : ;
ret = (c == '-') ? : (c - '');
while (c = getchar(), c >= '' && c <= '') ret = ret * + (c - '');
ret *= sgn;
return ;
}
template<typename N,typename PN>inline N flo(N a,PN b){return a>=?a/b:-((-a-)/b)-;}
template<typename N,typename PN>inline N cei(N a,PN b){return a>?(a-)/b+:-(-a/b);}
template<typename T>inline int sgn(T a) {return a>?:(a<?-:);}
template<class T> int countbit(const T &n) { return (n==)?:(+countbit(n&(n-))); }
template <class T1, class T2>
bool gmax(T1 &a, const T2 &b) { return a < b? a = b, :;}
template <class T1, class T2>
bool gmin(T1 &a, const T2 &b) { return a > b? a = b, :;}
template <class T> inline T lowbit(T x) {return x&(-x);} template<class T1, class T2>
ostream& operator <<(ostream &out, pair<T1, T2> p) {
return out << "(" << p.st << ", " << p.nd << ")";
}
template<class A, class B, class C>
ostream& operator <<(ostream &out, tuple<A, B, C> t) {
return out << "(" << get<>(t) << ", " << get<>(t) << ", " << get<>(t) << ")";
}
template<class T>
ostream& operator <<(ostream &out, vector<T> vec) {
out << "("; for(auto &x: vec) out << x << ", "; return out << ")";
}
void testTle(int &a){
while() a = a*(ll)a%;
}
const ll inf = 0x3f3f3f3f;
const ll INF = 1e17;
const int mod = 1e9+;
const double eps = 1e-;
const int N = +;
const double pi = acos(-1.0); /***********/ int quick(int x, long long n, int mod) {
int ans = ;
while(n) {
if(n&) ans = ans*x%mod;
x = x*x%mod;
n >>= ;
}
return ans;
} long long get2(long long n) {
long long ans = ;
while(n >>= )
ans += n;
return ans;
} int m[] = {, , , , }; //阶乘%5
int inv[] = {, , , , }; //i的逆元,写成i!的逆元,狂WA
pair<long long, int> get5(long long n) {
if(n < ) return {, m[n]};
pair<long long, int> ret = get5(n/);
ret.st += n/;
ret.nd = ret.nd*quick(m[], n/, )*m[n%]%;
return ret;
} int main() {
int T; scanf("%d", &T);
long long a[];
while(T--) {
int n; scanf("%d", &n);
long long sum = ;
for(int i = ; i < n; i++)
scanf("%lld", a+i), sum += a[i];
long long mod2 = get2(sum);
auto mod5 = get5(sum);
for(int i = ; i < n; i++) {
mod2 -= get2(a[i]);
auto ret = get5(a[i]);
mod5.st -= ret.st;
mod5.nd = mod5.nd*inv[ret.nd]%;
}
int ans;
if(mod5.st) ans = mod2? : ;
else {
ans = mod5.nd;
if(mod2) {
if(ans&) ans = (ans+)%;
}
else {
if(!(ans&)) ans = (ans+)%;
}
}
printf("%d\n", ans);
}
return ;
}
附:
一句话阐明如何求阶乘的末尾非0数:
求末尾非0数模5的值,n = 5k时,
n! = (1*2*3*4) * (6*7*8*9) * ... * (5k-4)*(5k-3)*(5k-2)*(5k-1) *5^k * k!
= (1*2*3*4/2) * (6*7*8*9/2) * ... * [(5k-4)*(5k-3)*(5k-2)*(5k-1)/2] *10^k * k!
= (1*2*3*4/2) * (6*7*8*9/2) * ... * [(5k-4)*(5k-3)*(5k-2)*(5k-1)/2] * k! (去掉末尾的几个零,结果不变)
= (1*2*3*4/2) * (6*7*8*9/2) * ... * [(5k-4)*(5k-3)*(5k-2)*(5k-1)/2] *6^k * k! (乘6,模5下末尾不变)
= (1*2*3*4*3) * (6*7*8*9*3) * ... * [(5k-4)*(5k-3)*(5k-2)*(5k-1)*3] * k!
= 2^k * k!
阶乘末两位非0数?
P = 4, B = 2;
P = 25, B = 5
再合并一下~

组合数求模
hihocoder1639 图书馆 [数学]的更多相关文章
- fopen的使用小记
整理自https://msdn.microsoft.com/zh-cn/library/t3ayayh1(VS.80).aspx errno, _doserrno, _sys_errlist, and ...
- 【转】科大校长给数学系学弟学妹的忠告&本科数学参考书
1.老老实实把课本上的题目做完.其实说科大的课本难,我以为这话不完整.科大的教材,就数学系而言还是讲得挺清楚的,难的是后面的习题.事实上做1道难题的收获是做10道简单题所不能比的. 2.每门数学必修课 ...
- MIT一牛人对数学在机器学习中的作用给的评述
MIT一牛人对数学在机器学习中的作用给的评述 转载自http://my.oschina.net/feedao/blog/52252,不过这个链接也是转载的,出处已经无从考证了. 感觉数学似乎总是不 ...
- [Swift]数学库函数math.h | math.h -- mathematical library function
常用数学函数 1. 三角函数 double sin (double);//正弦 double cos (double);//余弦 double tan (double);//正切 2 .反三角函数 d ...
- 数学思想:为何我们把 x²读作x平方
要弄清楚这个问题,我们得先认识一个人.古希腊大数学家 欧多克索斯,其在整个古代仅次于阿基米德,是一位天文学家.医生.几何学家.立法家和地理学家. 为何我们把 x²读作x平方呢? 古希腊时代,越来越多的 ...
- 速算1/Sqrt(x)背后的数学原理
概述 平方根倒数速算法,是用于快速计算1/Sqrt(x)的值的一种算法,在这里x需取符合IEEE 754标准格式的32位正浮点数.让我们先来看这段代码: float Q_rsqrt( float nu ...
- MarkDown+LaTex 数学内容编辑样例收集
$\color{green}{MarkDown+LaTex 数学内容编辑样例收集}$ 1.大小标题的居中,大小,颜色 [例1] $\color{Blue}{一元二次方程根的分布}$ $\color{R ...
- 深度学习笔记——PCA原理与数学推倒详解
PCA目的:这里举个例子,如果假设我有m个点,{x(1),...,x(m)},那么我要将它们存在我的内存中,或者要对着m个点进行一次机器学习,但是这m个点的维度太大了,如果要进行机器学习的话参数太多, ...
- Sql Server函数全解<二>数学函数
阅读目录 1.绝对值函数ABS(x)和返回圆周率的函数PI() 2.平方根函数SQRT(x) 3.获取随机函数的函数RAND()和RAND(x) 4.四舍五入函数ROUND(x,y) 5.符号函数SI ...
随机推荐
- 本地使用js或jquery操作cookie在谷歌浏览器chrome中不生效
一般是在本地调试cookie,无论使用jquery cookie插件还是js原生态cookie方法,在谷歌浏览器chrome中都不生效,这是什么原因? 原因是: chrome不支持js在本地操作coo ...
- SQLAlchemy并发写入引发的思考
背景 近期公司项目中加了一个积分机制,用户登录签到会获取登录积分,但会出现一种现象就是用户登录时会增加双倍积分,然后生成两个积分记录.此为问题 问题分析 项目采用微服务架构,下图为积分机制流程 ...
- Docker 自定义网络
1.创建自定义网络 docker network create -d bridge --subnet 172.25.0.0/16 network_name 2.redis docker 添加到网络 d ...
- Hyperledger Fabric 账本结构解析
前言 现在很多人都在从事区块链方面的研究,作者也一直在基于Hyperledger Fabric做一些开发工作.为了方便后来人更快的入门,本着“开源”的精神,在本文中向大家讲解一下Hyperledger ...
- 安装keystone时创建用户失败
系统:centos7.3 版本:openstack ocata 1.问题描述 安装keystone在创建用户时报错: The request you have made requires authen ...
- MariaDB远程连接问题
MariaDB在设置完通过Navicat Premium远程连接账号验证通过,但是无法正常使用工具的功能,只能使用sql语句查询,但是通过控制台命令功能正常. 经过修改账号权限,添加新用户等功能都无法 ...
- java基础学习总结——线程(二)
一.线程的优先级别
- 第26次Scrum会议(11/14)【欢迎来怼】
一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,阚博文 小组照片 二.开会信息 时间:2017/11/14 11:35~11:57,总计22min.地点:东北 ...
- 2018-2019-20172329 《Java软件结构与数据结构》第八周学习总结
2018-2019-20172329 <Java软件结构与数据结构>第八周学习总结 现在对于我而言,最珍贵的是时间,感觉自己在时间飞逝的时候真的挽留不住什么,只能怒发冲冠的让自己疯狂的学习 ...
- 2018-2019-20172321 《Java软件结构与数据结构》第六周学习总结
2018-2019-20172321 <Java软件结构与数据结构>第六周学习总结 教材学习内容总结 第10章 树 10.1概述 树由一个包含结点和边的集构成,其中的元素被储存在这些结点中 ...