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. [算法]欧拉定理+ ...
随机推荐
- .NET应用架构设计—四色原型模式(色彩造型、域无关的模型)(概念版)
阅读文件夹: 1.背景介绍 2.问自己,UML对你来说有意义吗?它帮助过你对系统进行分析.建模吗? 3.一直以来事实上我们被一个缝隙隔开了,使我们对OOAD遥不可及 4.四色原型模式填补这个历史缝隙, ...
- SQL_sql的简单查询
***********************************************声明*************************************************** ...
- scala 101
* scala 安装: 下载可以执行的文件. 注意版本. spark 0.8.0 对应的scala 为2.9.3 * scala 编译: 和java 很像: 1, 直接编译脚本: scalac H ...
- git branch(转)
git branch git branch 不带参数:列出本地已经存在的分支,并且在当前分支的前面加“*”号标记,例如: #git branch* master newbranch gi ...
- 2014在百度之星资格赛的第四个冠军Labyrinth
Problem Description 熊度仅仅是一种冒险的熊,一个偶然落入一个m*n迷宫矩阵,能从矩阵左上角第一个方格開始走,仅仅有走到右上角的第一个格子才算走出迷宫.每一次仅仅能走一格,且仅仅能向 ...
- ACM算法
一.数论算法 1.求两数的最大公约数 2.求两数的最小公倍数 3.素数的求法 A.小范围内判断一个数是否为质数: B.判断longint范围内的数是否为素数(包含求50000以内的素数表): 二. ...
- 用grunt搭建自动化的web前端开发环境
用grunt搭建自动化的web前端开发环境 jQuery在使用grunt,bootstrap在使用grunt,百度UEditor在使用grunt,你没有理由不学.不用! 1. 前言 各位web前端开发 ...
- 1006-HBase操作实战(JAVA API状态)
一.准备阶段 开发环境: hadoop: hadoop -2.4.0 hbase: hbase -0.94.11-security eclipse:Juno Service Release 2 二.创 ...
- CUMCM--总结
有些事情经历一次就好,一次的经历足以成长. 其实,对于数模真的没什么要说的,也没什么好写的.从9月11日,8点见到赛题,到今天早上8点的提交,短短的三天,度过寂静的黑夜,见到微曦的黎明.三天三夜,9个 ...
- Linq入门演练---(1)基本用法-分组,排序,内连接
这一节大家共同学习下LINQ的基本用法,主要包括LINQ的分组,排序,和内外连接. 1.分组 基本语法: group element by key element 表示查询结果返回的元素,key表示 ...