【BZOJ3884】上帝与集合的正确用法
Description
一句话题意,给定\(p\)作为模数:
\(p\le 10^7\),数据组数\(T\le1000\)。
Solution
看到就弃疗了,再见......
将模数\(p\)拆分成\(p=q2^k\),其中\(q\)为一个奇数。那么:
2^{2^{2...}}mod\; p&=2^k(2^{2^{2..}-k}mod\;q)\\
&=2^k(2^{(2^{2..}-k)mod\;\varphi(q)}mod\;q)
\end{aligned}
\]
考虑递归计算\((2^{2...}-k)\)的\(2^{2...}\),只不过模数由\(p\)变成\(\varphi(q)\)。当模数\(p\)变成1的时候,我们就遇到了边界——不管里面式子如何,模1都是0,直接返回0即可。考虑递归的层数:除了第一次调用的\(p\)可能是奇数之外,往下递归的\(p\)几乎都是偶数(\(\varphi(x),x\ge3\)都是偶数),\(\varphi(q)\)相对于\(p\)大概会减少一倍。直到\(p=1\)时,层数不会太多,dalao说是\(O(log^2p\))。
所以就直接递归计算了。实现上,如果先用线性筛筛出所有的\(\varphi\),太慢。每次调用\(\varphi\)时直接\(O(\sqrt n)\)计算反而更加快。这两种方法,是稳定300ms和6ms的差距......
Code
#include <cstdio>
using namespace std;
const int S=10000001;
inline int ksm(int x,int y,int MOD){
int res=1;
for(;y;x=1LL*x*x%MOD,y>>=1)
if(y&1) res=1LL*res*x%MOD;
return res;
}
int getPhi(int x){
int res=x;
for(int i=2;i*i<=x;i++){
if(!(x%i)) res-=res/i;
while(!(x%i)) x/=i;
}
if(x!=1) res-=res/x;
return res;
}
int calc(int p){
if(p==1) return 0;
int k=0,q=p;
while(!(q&1)) k++,q>>=1;
int phiq=getPhi(q);
int mi=(calc(phiq)-k)%phiq;
if(mi<0) mi+=phiq;
return 1LL*ksm(2,mi,q)*ksm(2,k,p)%p;
}
int main(){
int T,p;
scanf("%d",&T);
while(T--){
scanf("%d",&p);
printf("%d\n",calc(p));
}
return 0;
}
【BZOJ3884】上帝与集合的正确用法的更多相关文章
- bzoj3884上帝与集合的正确用法
Description 根据一些书上的记载,上帝的一次失败的创世经历是这样的: 第一天, 上帝创造了一个世界的基本元素,称做“元”. 第二天, 上帝创造了一个新的元素,称作“α”.“α”被定义为“ ...
- BZOJ3884: 上帝与集合的正确用法 拓展欧拉定理
Description 根据一些书上的记载,上帝的一次失败的创世经历是这样的: 第一天, 上帝创造了一个世界的基本元素,称做“元”. 第二天, 上帝创造了一个新的元素,称作“α”.“α”被定义为“ ...
- BZOJ3884: 上帝与集合的正确用法(欧拉函数 扩展欧拉定理)
Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 3860 Solved: 1751[Submit][Status][Discuss] Descripti ...
- bzoj3884 上帝与集合的正确用法
a^b mod P=a^(b mod phi(p)) mod p,利用欧拉公式递归做下去. 代码 #pragma comment(linker,"/STACK:1024000000,1024 ...
- bzoj3884: 上帝与集合的正确用法 欧拉降幂公式
欧拉降幂公式:http://blog.csdn.net/acdreamers/article/details/8236942 糖教题解处:http://blog.csdn.net/skywalkert ...
- bzoj3884: 上帝与集合的正确用法 扩展欧拉定理
题意:求\(2^{2^{2^{2^{...}}}}\%p\) 题解:可以发现用扩展欧拉定理不需要很多次就能使模数变成1,后面的就不用算了 \(a^b\%c=a^{b\%\phi c} gcd(b,c) ...
- bzoj千题计划264:bzoj3884: 上帝与集合的正确用法
http://www.lydsy.com/JudgeOnline/problem.php?id=3884 欧拉降幂公式 #include<cmath> #include<cstdio ...
- BZOJ3884 上帝与集合的正确用法(欧拉函数)
设f(n)为模n时的答案,由2k mod n=2k mod φ(n)+φ(n) mod n(并不会证),且k mod φ(n)=f(φ(n)),直接就可以得到一个递推式子.记搜一发即可. #inclu ...
- bzoj3884: 上帝与集合的正确用法(数论)
感觉是今天洛谷月赛T3的弱化版,会写洛谷T3之后这题一眼就会写了... 还是欧拉扩展定理 于是就在指数上递归%phi(p)+phi(p)直到1,则后面的指数就都没用了,这时候返回,边回溯边快速幂.因为 ...
- [bzoj3884]上帝与集合的正确用法——欧拉函数
题目大意 题解 出题人博客 代码 #include <bits/stdc++.h> using namespace std; const int M = 10001000; int phi ...
随机推荐
- 人工智能AI芯片与Maker创意接轨 (中)
在人工智能AI芯片与Maker创意接轨(上)这篇文章中,介绍人工智能与深度学习,以及深度学习技术的应用,了解内部真实的作业原理,让我们能够跟上这波AI新浪潮.系列文来到了中篇,将详细介绍目前市面上的各 ...
- GearCase UI v0.2 版本
12 月闲暇的时间一直在更新 GearCase.通过不懈的努力,GearCase 今天迎来了一次中间版本的更新,这次的更新主要加入了 Springs 动画组件,部分组件也添加了此组件的动画效果. &g ...
- ClassLoader.loadClass()与Class.forName()的区别
ClassLoader.loadClass()与Class.forName()都是反射用来构造类的方法,但是他们的用法还是有一定区别的. 在讲区别之前,我觉得很有不要把类的加载过程在此整理一下. 在J ...
- Excel VBA宏 链接服务器 上传和下载数据
首先说明以下. 第一: 下面的 “ _" 也就是 空格下划线 在VBA中表示换行的意思:& 表示链接连个字符串的操作,注意 & 的前后是否需要空格 第二: 如果链接服务器,服 ...
- cobbler部署以及使用
常用软件安装及使用目录 资源链接:https://pan.baidu.com/s/1yfVnuSgY5vOTh-B74tpVyw 网盘分享的文件在此 cobbler第一次操作history. ec ...
- Python基础_内置函数
Built-in Functions abs() delattr() hash() memoryview() set() all() dict() help() min() setat ...
- 20162314 《Program Design & Data Structures》Learning Summary Of The Second Week
20162314 2017-2018-1 <Program Design & Data Structures>Learning Summary Of The Second Week ...
- linux 常用命令-编辑模式
1.编辑模式就是通过vi或者vim打包文件,进入编辑模式,vim是vi的升级版,vim除了报错vi的命令外还包括一些额外的命令,本文以vim命令为例,如果需要查询而不需要编辑文件则可以通过cat命令查 ...
- 一个关于狗记录的Java练习
package 狗场;import java.util.*;public class dogRoom { /** * 作者.范铭祥 * 狗场的狗体重查询问题 */ public static void ...
- 树莓派与Arduino Leonardo使用NRF24L01无线模块通信之基于RF24库 (六) 树莓派查询子节点温湿度数据
nrl24l01每次只能发送4个字节,前面说到,第一个字节用于源节点,第二个字节用于目的节点.因此只剩下两个字节用于温度和湿度,一个字节只有八位,需要表示温湿度的正负数,因此每个字节的第一位表示正负符 ...