1951: [Sdoi2010]古文字猪
1951: [Sdoi2010]古代猪文
链接:Click Here~
题目:
一道非常好的组合数学题。!!。题目非常长。只是就以下几段话实用。
iPig认为仅仅要符合文献,每一种能整除N的k都是有可能的。他打算考虑到全部可能的k。显然当k等于某个定值时,该朝的猪文文字个数为N / k。然而从N个文字中保留下N / k个的情况也是相当多的。iPig估计,假设全部可能的k的全部情况数加起来为P的话。那么他研究古代文字的代价将会是G的P次方。 如今他想知道猪王国研究古代文字的代价是多少。
因为iPig认为这个数字可能是天文数字。所以你仅仅须要告诉他答案除以999911659的余数就能够了。
就是要求出P = C(N,i|N),然后解出G^P % 999911659就是最后的答案。
我们能够非常easy的看出问题是由两部分组成的,求解G^P和P。
我们能够easy的得出G^P用高速幂能够easy的解决,如今的问题是怎样高速的求出P呢?这是一个难题。我们在继续的分解,发现P的组成了没有。对!就是组合公式C(N,i|N)!而我们又能够知道组合公式假设数据较小的时候能够用杨辉三角的暴力公式得到。而假设是大组合数的话就要用到Lucas定理。(AekdyCoin空间给出了这方面的具体说明)而这题的组合数显然是大组合数。
而直接求就算是long
long 也要益处啊!
!怎么办?我们能够想到大组合数的通常处理方法。就是取模。
模?哪来的模?而此时我们又有费马小定理能够知道当P是素数的时候:
G^P % MOD = G ^ (P % (MOD - 1)) % MOD
所以,此时MOD - 1 = 999911658 是一个偶数,如今就不符合Lucas定理了。
所以,此时我们要对这个偶数进行质数分解。999911658 = 2 * 3 * 4679 * 35617 可是,如今问题又来了。你把模给分解了,那怎样求出结果呢?
我们在好好研究一下。你发现了什么没有?对!就是有例如以下的等式关系:
x = a1 % m1
x = a2 % m2
x = a3 % m3
.
.
.
.
对!
就是中国剩余定理!
如今。经过了一步一步的分解最终把问题攻克了。你该懂了吧!
一道神题啊!
!
/*
算法:模非素数的组合数
题目:就是要求出P = C(N,i|N),然后解出G^P % 999911659
1、对模质因子分解
2、中国剩余定理
1 <= G <= 10^9,1 <= N <= 10^9 */
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std; typedef long long LL;
const int phi = 999911658;
const int MOD = 999911659;
const int MAXN = 200000; struct Prim{
int cnt,prim[MAXN],num[MAXN];
}pz,nz; int n,G;
LL a[MAXN];
LL fact[5][37777]; //分解质因子
void Div(Prim& p,int x){
p.cnt = 0; //初始化
int k = sqrt(x + 0.5);
for(int i = 2;i <= k;++i){
if(0 == x % i){
p.num[++p.cnt] = 0;
p.prim[p.cnt] = i;
while(0 == x % i){
++p.num[p.cnt];
x /= i;
}
}
} if(x > 1){
p.num[++p.cnt] = 1;
p.prim[p.cnt] = x;
}
} //预处理阶乘
void init(){
int i,j;
for(i = 1;i <= pz.cnt;++i){
fact[i][0] = 1;
for(j = 1;j <= pz.prim[i];++j)
fact[i][j] = fact[i][j-1] * j % pz.prim[i];
}
} //高速幂取模
LL powmod(LL a,LL b,const int& mod){
LL res = 1;
a %= mod; while(b > 0){
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
} return res;
} LL Norma_C(int n,int m,int i){
int p = pz.prim[i];
return fact[i][n] * powmod(fact[i][m]*fact[i][n-m]%p,p-2,p) % p;
} //Lucas
LL Lucas(int n,int m,int i){
if(!m) return 1;
int p = pz.prim[i];
if(n%p < m%p) return 0;
LL tmp = Norma_C(n%p,m%p,i);
return tmp * Lucas(n / p,m / p,i) % p;
} //计算C(N,i)
void deal(int sum){
for(int i = 1;i <= pz.cnt;++i){
a[i] = (a[i] + Lucas(n,sum,i)) % pz.prim[i];
}
} //查找 i|N
void dfs(int dep,int sum){
if(dep > nz.cnt){
deal(sum);
return;
} dfs(dep+1,sum); //不要该数
for(int i = 1;i <= nz.num[dep];++i){ //要该数的情况
sum *= nz.prim[dep];
dfs(dep+1,sum);
}
} //扩展欧几里得
void extgcd(LL a,LL b,LL& d,LL& x,LL& y){
if(!b){ d = a; x = 1; y = 0; }
else { extgcd(b,a % b,d,y,x); y -= x * (a / b); }
} //中国剩余定理
LL china(){
LL M = phi,d,y,x = 0;
for(int i = 1;i <= pz.cnt;++i){
LL w = M / pz.prim[i];
extgcd(pz.prim[i],w,d,d,y);
x = (x + y * w * a[i]) % M;
}
x = (x + M) % M;
return x;
} int main()
{
while(~scanf("%d%d",&n,&G)){
memset(a,0,sizeof(a));
G %= MOD;
if(!G){
puts("0");
continue;
} //////////////////////////////// Div(pz,phi); //对模进行质因子分解
Div(nz,n); //对数进行质因子分解
init(); //预处理阶乘
dfs(1,1);
LL ans = china(); //中国剩余定理 ////////////////////////////////// printf("%lld\n",powmod((LL)G,ans,MOD)); //G^P
}
return 0;
}
1951: [Sdoi2010]古文字猪的更多相关文章
- BZOJ 1951: [Sdoi2010]古代猪文( 数论 )
显然答案是G^∑C(d,N)(d|N).O(N^0.5)枚举N的约数.取模的数999911659是质数, 考虑欧拉定理a^phi(p)=1(mod p)(a与p互质), 那么a^t mod p = a ...
- 1951: [Sdoi2010]古代猪文
1951: [Sdoi2010]古代猪文 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 2171 Solved: 904[Submit][Status] ...
- BZOJ 1951: [Sdoi2010]古代猪文 [Lucas定理 中国剩余定理]
1951: [Sdoi2010]古代猪文 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 2194 Solved: 919[Submit][Status] ...
- bzoj 1951 [Sdoi2010]古代猪文(数论知识)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1951 [思路] 一道优(e)秀(xin)的数论题. 首先我们要求的是(G^sigma{ ...
- 【刷题】BZOJ 1951 [Sdoi2010]古代猪文
Description "在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心--" --选自猪王国民歌 很久 ...
- bzoj 1951 [Sdoi2010]古代猪文 ——数学综合
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1951 数学综合题. 费马小定理得指数可以%999911658,又发现这个数可以质因数分解.所 ...
- bzoj 1951: [Sdoi2010]古代猪文
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #defin ...
- BZOJ.1951.[SDOI2010]古代猪文(费马小定理 Lucas CRT)
题目链接 \(Description\) 给定N,G,求\[G^{\sum_{k|N}C_n^k}\mod\ 999911659\] \(Solution\) 由费马小定理,可以先对次数化简,即求\( ...
- 【BZOJ】1951[Sdoi2010]古代猪文
[题意]给定G,N,求: $$ans=G^{\sum_{i|n}\binom{n}{i}}\ \mod\ \ p$$ 1<=N,G<=10^9,p=999911659. [算法]欧拉定理+ ...
随机推荐
- 013实现使用两个堆栈队列(keep it up)
实现使用两个堆栈队列 FIFO队列是一种数据结构(FIFO),后堆叠前进出的数据结构的(FILO). 两个栈实现的最简单的方法就是排队:队列中的第一个推栈, 队列将数据顺序的第一个堆栈推入第二堆叠 ...
- [6] 算法路 - 双向冒泡排序的Shaker
Shaker序列 –算法 1. 气泡排序的双向进行,先让气泡排序由左向右进行.再来让气泡排序由右往左进行,如此完毕一次排序的动作 2. 使用left与right两个旗标来记录左右两端已排序的元素位置. ...
- Oracle存储过程详解(引用)+补充(转) dbms_output包 good
执行存储过程时,execute和call的区别 EXEC is a sqlplus command that put its argument as an anonymous pl/sql block ...
- IT只忍者龟Photoshop简单人像的头发抠图过程
一.导入素材,加入蒙版 1.导入美女图片 2.导入背景图片 如今须要将美女抠出来放在这个背景上,怎么办?一定会有人想到用通道,抽出.(备注:在ps6以后版本号,抽出已经没有这个选项了). 3.将美女图 ...
- Flux是一个Facebook团队的前端开发架构
Flux是一个Facebook团队的前端开发架构 Flux introduction 本文组成: React 官方文档翻译 相关实践心得. 内容上是Flux的介绍,例子将会在以后写出.一旦稍微多了解一 ...
- Linux netstat订购具体解释
简单介绍 Netstat 命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics).masquerade 连接.多播成员 (Multicast Memb ...
- Matlab与.NET基于类型安全的接口混合编程入门
原文:[原创]Matlab与.NET基于类型安全的接口混合编程入门 如果这些文章对你有用,有帮助,期待更多开源组件介绍,请不要吝啬手中的鼠标. [原创分享]Matlab.NET混编调用Figure窗体 ...
- HDU 5052 Yaoge’s maximum profit 光秃秃的树链拆分 2014 ACM/ICPC Asia Regional Shanghai Online
意甲冠军: 特定n小点的树权. 以下n每一行给出了正确的一点点来表达一个销售点每只鸡价格的格 以下n-1行给出了树的侧 以下Q操作 Q行 u, v, val 从u走v,程中能够买一个鸡腿,然后到后面卖 ...
- 【关节点+桥】关节点和桥模板 Tarjan
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; con ...
- iOS ... NS_REQUIRES_NIL_TERMINATION
看到官方的一个样例不错,这里留记. #import <Cocoa/Cocoa.h> @interface NSMutableArray (variadicMethodExample) - ...