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 ...
随机推荐
- 【Jmeter测试】接口请求完成后,查询数据库结果,检测数据存储是否正确
Jmeter脚本逻辑 发送POST请求,把数据保存到数据库中 发讯数据库,数据库查询结果保存的变量中 使用BeanShell判断数据库查询结果 Jmeter脚本结构 第一个箭头指的是JDBC Conn ...
- selenium 定位不到元素总结
元素在网页上,却会出现定位不到的情况的分析. 1. 定位不正确. 2. 页面还没有加载完就去查找元素了. 3. 有遮罩层. 首先说下第3点. 先前在公司遇到过这样的问题. 页面是显示出来了, 这个元素 ...
- WebGL——osg框架学习三
今天继续来Draw绘制的osg模块的学习,昨天我们学习的是StateBin渲染状态树节点类,今天我们来继续学习下一个Draw的基础类DrawableEntity渲染对象实体类.这个类和Drawable ...
- 记一次RMI的调用数据失误
这两天在测试一个Spring RMI接口的时候,出现了个奇怪的问题.Server端返回的数据,到了客户端出现了属性丢失的情况. 类继承体系 .客户端里面定义在ClassA中的属性全部为null. 分析 ...
- Netty源码分析第3章(客户端接入流程)---->第5节: 监听读事件
Netty源码分析第三章: 客户端接入流程 第五节: 监听读事件 我们回到AbstractUnsafe的register0()方法: private void register0(ChannelPro ...
- ats Linux路由器上内联
路由设置假定客户端集在单个物理接口后面的不同网络上. 出于本例的目的,我们将假设: 客户端位于172.28.56.0/24网络上路由器连接网络172.28.56.0/24和192.168.1.0/24 ...
- linux命令系列 ls
ls是linux中最常用的命令之一 ls 的功能是list directory contents,其常用的选项如下: (1) -l use a long listing format(长格式,显示 ...
- Daily Scrumming 2015.10.20(Day 1)
一.今明两天任务表 Member Today’s Task Tomorrow’s Task 江昊 购买服务器,搭建服务器,配置服务器端用户与权限管理 配置ruby与rails环境 配置mysql与数据 ...
- 使用myeclipse2014整合ss2h
使用myeclipse2014整合ssh 新建一个webproject 创建过程中注意选择生成web.Xml 先添加struts2的能力 选择都添加过滤器的选项 Core dojo Dwr spr ...
- java 框架 面试 2
1.谈谈你对Struts的理解. 答: 1. struts是一个按MVC模式设计的Web层框架,其实它就是一个大大的servlet,这个Servlet名为ActionServlet,或是ActionS ...