BZOJ1951 古代猪文

题目链接

题意:

计算\(g^{\sum_{k|n}(^n_k)}\%999911659\)

\(n\le 10^9, g\le 10^9\)

题解:

首先,根据扩展欧拉定理,\(a^b≡a^{b\%\phi(p)}\ (MOD\ p), gcd(a,p)=1\)

可以把要计算的式子降幂得到:\(g^{(\sum_{k|n}(^n_k))\%999911658}\%999911659\)

接下来我们需要计算的就是\((\sum_{k|n}(^n_k))\%999911658\)

但是要是直接计算是不现实的,一是组合数要用到\(n\)的阶乘,而\(n\)有\(10^9\)的大小,其次要算的阶乘的逆元也不一定存在

可以发现\(999911658\)可以拆分成\(2\times 3\times 4679\times 35617\)

所以我们可以计算出\(\sum_{k|n}(^n_k)\)在四个质数下的模数,然后用中国剩余定理来合并

也就是说,求出来在四个模数下的值\(r_1,r_2,r_3,r_4\)之后,得到一个线性方程组:

\[\begin{cases}
x≡r_1\ (MOD\ 2) \\
x≡r_2\ (MOD\ 3) \\
x≡r_3\ (MOD\ 4679) \\
x≡r_4\ (MOD\ 35617)
\end{cases}\]

用中国剩余定理合并一下就可以得到\(x\)在模\(999911658\)下的值了

然后用快速幂就可以计算出最后的答案

而拆分后的质数都比较小,所以可以用卢卡斯定理来算在小质数下的组合数

view code
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const LL MOD = 999911659LL;
const int MAXN = 4e4+7;
LL fact[MAXN];
vector<LL> P,F;
LL n, g;
void preprocess(){
LL x = MOD - 1;
for(int i = 2; i * i <= x; i++){
if(x%i==0){
P.push_back(i);
while(x%i==0) x /= i;
}
}
if(x!=1) P.push_back(x);
for(int i = 1; i * i <= n; i++){
if(n%i==0){
F.push_back(i);
if(i!=n/i) F.push_back(n/i);
}
}
}
LL ksm(LL a, LL b, LL p){ // a^b%p
LL ret = 1;
while(b){
if(b&1) ret = ret * a % p;
b >>= 1;
a = a * a % p;
}
return ret;
}
void exgcd(LL a, LL b, LL &x, LL &y){ //ax + by = 1
if(!b){ x = 1, y = 0; return; }
exgcd(b,a%b,y,x);
y -= a / b * x;
}
void calComb(LL p){ // 预处理组合数
fact[0] = 1;
for(int i = 1; i < p; i++) fact[i] = fact[i-1] * i % p;
}
LL inv(LL a, LL p){ // a在模p意义下的逆元
LL x, y;
exgcd(a,p,x,y);
return (x%p)+p;
}
LL C(LL n, LL m, LL p){ return n<m?0:fact[n] * inv(fact[m],p) % p * inv(fact[n-m],p) % p; } // 组合数C(n,m)%p
LL lucas(LL n, LL m, LL p){ // 卢卡斯计算 C(n,m) % p
LL ret = 1;
while(n and m){
int nn = n % p, mm = m % p;
if(mm>nn) return 0LL;
ret = ret * C(nn,mm,p) % p;
n /= p; m /= p;
}
return ret;
}
LL CRT(vector<LL> R, vector<LL> P){
LL ret = 0;
for(int i = 0; i < (int)R.size(); i++)
ret = (ret + R[i] * (MOD-1)/P[i] % (MOD-1) * inv((MOD-1)/P[i],P[i])) % (MOD-1);
return ret;
}
LL solve(){
preprocess();
vector<LL> R;
for(int p : P){
calComb(p);
LL r = 0;
for(int f : F) r = (r + lucas(n,f,p)) % p;
R.push_back(r);
}
LL pw = CRT(R,P);
return ksm(g,pw,MOD);
}
int main(){
scanf("%lld %lld",&n,&g);
g %= MOD;
if(g == 0) cout << 0 << endl;
else if(g == 1) cout << 1 << endl;
else cout << solve() << endl;
return 0;
}

BZOJ1951 古代猪文 【数论全家桶】的更多相关文章

  1. 【bzoj1951】: [Sdoi2010]古代猪文 数论-中国剩余定理-Lucas定理

    [bzoj1951]: [Sdoi2010]古代猪文 因为999911659是个素数 欧拉定理得 然后指数上中国剩余定理 然后分别lucas定理就好了 注意G==P的时候的特判 /* http://w ...

  2. BZOJ-1951 古代猪文 (组合数取模Lucas+中国剩余定理+拓展欧几里得+快速幂)

    数论神题了吧算是 1951: [Sdoi2010]古代猪文 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1573 Solved: 650 [Submit ...

  3. 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 ...

  4. bzoj1951 [Sdoi2010]古代猪文 ——数论综合

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1951 题意就是要求 G^( ∑(k|n) C(n,k) ) % p,用费马小定理处理指数,卢 ...

  5. luogu 2480 古代猪文 数论合集(CRT+Lucas+qpow+逆元)

    一句话题意:G 的 sigma d|n  C(n d) 次幂  mod 999911659 (我好辣鸡呀还是不会mathjax) 分析: 1.利用欧拉定理简化模运算 ,将上方幂设为x,则x=原式mod ...

  6. 【BZOJ1951】[SDOI2010]古代猪文

    [BZOJ1951][SDOI2010]古代猪文 题面 bzoj 洛谷 题解 题目实际上是要求 $ G^{\sum d|n\;C_n^d}\;mod \; 999911659 $ 而这个奇怪的模数实际 ...

  7. 【BZOJ1951】古代猪文(CRT,卢卡斯定理)

    [BZOJ1951]古代猪文(CRT,卢卡斯定理) 题面 BZOJ 洛谷 题解 要求什么很显然吧... \[Ans=G^{\sum_{k|N}{C_N^k}}\] 给定的模数是一个质数,要求解的东西相 ...

  8. 【BZOJ1951】[Sdoi2010]古代猪文 Lucas定理+CRT

    [BZOJ1951][Sdoi2010]古代猪文 Description 求$X=\sum\limits_{d|n}C_n^d$,$Ans=G^X (\mod 999911659)$. Input 有 ...

  9. 【题解】古代猪文 [SDOI2010] [BZOJ1951] [P2480]

    [题解]古代猪文 [SDOI2010] [BZOJ1951] [P2480] 在那山的那边海的那边有一群小肥猪.他们活泼又聪明,他们调皮又灵敏.他们自由自在生活在那绿色的大草坪,他们善良勇敢相互都关心 ...

随机推荐

  1. C++把数字排序

    C++把数字排序 描述 思路 代码 描述 如题,详细如下: 输入不超过1024个数字,以特殊数字结尾,如(-999),把数字从小到大排序. 思路 目前,我们有两种思路可以写: 1是 在输入的时候,排序 ...

  2. dbms_job和dbms_job基础学习

    一.dbms_job学习 a.创建job: dbms_job.submit(jobno,what,next_date,interval);b.删除job: dbms_job.remove(jobno) ...

  3. 70.LeetCode爬楼梯

    爬楼梯 点击标题可跳转到官网进行查看 假设你正在爬楼梯.需要 n 阶你才能到达楼顶. 每次你可以爬 1 或 2 个台阶.你有多少种不同的方法可以爬到楼顶呢? 注意:给定 n 是一个正整数. 示例 1: ...

  4. 屏蔽每分钟SSH尝试登录超过10次的IP

    屏蔽每分钟SSH尝试登录超过10次的IP 方法1:通过lastb获取登录状态: #!/bin/bash DATE=$(date +"%a %b %e %H:%M") #星期月天时分 ...

  5. MySQL下载与安装教程

    一,下载篇 1,首先访问MySQL官网下载页,https://dev.mysql.com/downloads/mysql/ 如果是MAC系统,操作系统请选择macOS,Windows则选择Window ...

  6. luogu P2198 杀蚂蚁

    题目描述 经过小FF的研究,他发现蚂蚁们每次都走同一条长度为n个单位的路线进攻, 且蚂蚁们的经过一个单位长度所需的时间为T秒.也就是说,只要小FF在条路线上布防且给蚂蚁造成沉痛伤害就能阻止蚂蚁的进军. ...

  7. [Usaco2007 Jan]Telephone Lines架设电话线

    题目描述 FarmerJohn打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务.于是,FJ必须为此向电信公司支付一定的费用.FJ的农场周围分布着N(1<=N<=1,000)根 ...

  8. 1.5V升3V芯片和电路图,DC-DC升压IC

    1.5V升3V的升压芯片,3V给LED供电,或者单片机模块供电等. PW5200A工作频率为1.4MHZ.轻载时自动PWM/PFM模式切换,提高效率. PW5200A能够提供2.5V和5V之间的可调输 ...

  9. Py-多态,封装,反射,描述符,包装标准类型,面向对象进阶

    多态: 对象可以通过他们共同的属性和动作来访问,而不需要考虑他们的类多态是继承的应用 class H2o: def __init__(self,temp): self.temp=temp def ht ...

  10. java虚拟机入门(二)-探索内存世界

    上节简单介绍了一下jvm的内存布局以及简单概念,那么对于虚拟机来说,它是怎么一步步的让我们能执行方法的呢: 1.首先,jvm启动时,跟个小领导一样会根据配置参数(没有配置的话jvm会有默认值)向大领导 ...