2019ICPC南京网络赛B super_log——扩展欧拉定理
题目
设函数
$$log_a*(x) = \begin{cases}
-1, & \text{ if } x < 1 \\
1+log_a*(log_ax) & \text{ if } x \geq 1
\end{cases}$$
求最小的正整数 $x$,使得 $log_a*(x) \geq b$
分析
通过将递归式展开,展开 $b$ 次等于1,所以 $x$ 为 $a^{a^{a^{...}}}$(共 $b$ 次)
由欧拉降幂公式
$$a^b= \begin{cases} a^{b \% \varphi(p)} & gcd(a,p)=1 \\ a^b & gcd(a,p)\neq 1,b < \varphi (p) \\ a^{b\% \varphi (p) + \varphi (p)} & gcd(a,p)\neq 1,b \geq \varphi (p) \end{cases}$$
用这个公式,需要讨论 $b$ 与 $\varphi(p)$ 的大小关系,很麻烦。
看网上的博客,有一种精妙的方法,只需重写 Mod 函数,就能当作 $a$ 与 $p$ 互素处理。证明见博客。
要点:
- 快速幂和cal函数都要换成Mod;
- 最终答案需要模p
#include<bits/stdc++.h>
using namespace std; typedef long long ll;
ll a, b, p; ll Mod(ll x, ll mod)
{
return x < mod ? x : x % mod + mod;
} ll euler_phi(ll n)
{
ll m = (ll)sqrt(n + 0.5);
ll ans = n;
for (ll i = ; i <= m; i++)
{
if (n % i == )
{
ans = ans / i * (i - );
while (n % i == ) n /= i; //除尽
}
}
if (n > ) ans = ans / n * (n - ); //剩下的不为1,也是素数
return ans;
} ll qpow(ll a, ll b, ll p)
{
ll ret = ;
while(b)
{
if(b&) ret = Mod(ret * a, p);
a = Mod(a * a ,p);
b >>= ;
}
return ret;
} ll cal(ll a, ll b, ll p) //a^a^a..^a共b次
{
// printf("%lld %lld\n", t, p);
//if(t == 1) return Mod(a, p);
if(b == ) return Mod(, p);
if(p == ) return Mod(a, p);
ll phip = euler_phi(p);
return qpow(a, cal(a, b-, phip), p); //第一类和第三类
} int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%lld%lld%lld", &a, &b, &p);
printf("%lld\n", cal(a, b, p) % p); //这个取模不能少
}
return ;
}
之前写了一种需要讨论 $b$ 与 $\varphi(p)$ 大小的,
因为模数 $p \leq 1e6$,可以找找 $b$ 小于 $\varphi(p)$ 的情况
打表发现,
当次数大于3时,只有 $a=2$ 可能小于 $\varphi(p)$,特判一下就好了。
#include<bits/stdc++.h>
using namespace std; typedef long long ll;
ll a, b, p;
int table[] = {, , , ,}; ll qpow(ll a, ll b, ll p)
{
a = a%p;
ll ret = %p;
while(b)
{
if(b&) ret = ret*a%p;
a = a*a%p;
b >>= ;
}
return ret%p;
} ll euler_phi(ll n)
{
ll m = (ll)sqrt(n + 0.5);
ll ans = n;
for (ll i = ; i <= m; i++)
{
if (n % i == )
{
ans = ans / i * (i - );
while (n % i == ) n /= i; //除尽
}
}
if (n > ) ans = ans / n * (n - ); //剩下的不为1,也是素数
return ans;
} ll f(ll p, ll t)
{
//printf("%lld %lld\n", p, t);
if(t == ) return a%p;
if(t == ) return qpow(a, a, p);
if(t == ) return %p;
if(p == ) return ;
ll phip = euler_phi(p);
if(p % a == ) //t >= 3,若出现第二种情况,a只能为2
{
if(a == && t <= && table[t-] < phip)
//return qpow(a, f(p, t-1), p);
return table[t]%p;
}
return qpow(a, f(phip, t-)+phip, p); //第一类和第三类
} int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%lld%lld%lld", &a, &b, &p);
printf("%lld\n", f(p, b));
}
return ;
}
参考链接:https://blog.csdn.net/qq_35914587/article/details/79883547
2019ICPC南京网络赛B super_log——扩展欧拉定理的更多相关文章
- 2019ICPC南京网络赛B super_log
题意:求a的a的a次方..一直求b次,也就是在纸上写个a,然后一直a次方a次方,对m取模,记为F(a,b,m)=pow(a,F(a,b-1,phi(m)) 解题思路:联系欧拉降幂,这个迭代的过程,我们 ...
- 2019ICPC南京网络赛B super_log(a的b塔次方)
https://nanti.jisuanke.com/t/41299 分析:题目给出a,b,mod求满足条件的最小a,由题目的式子得,每次只要能递归下去,b就会+1,所以就可以认为b其实是次数,什么的 ...
- 2019ICPC南京网络赛A题 The beautiful values of the palace(三维偏序)
2019ICPC南京网络赛A题 The beautiful values of the palace https://nanti.jisuanke.com/t/41298 Here is a squa ...
- 2019 南京网络赛 B super_log 【递归欧拉降幂】
一.题目 super_log 二.分析 公式很好推出来,就是$$a^{a^{a^{a^{...}}}}$$一共是$b$个$a$. 对于上式,由于指数太大,需要降幂,这里需要用到扩展欧拉定理: 用这个定 ...
- 2019icpc南京网络赛
B. super_log(扩展欧拉函数) 题意:求aa...(b个a)模M的值. 思路:递归用欧拉函数求解,我们知道欧拉降幂公式: 如果讨论b和φ(p)的关系会很麻烦,网上证明了一种精妙的方法,只需重 ...
- The Preliminary Contest for ICPC Asia Nanjing 2019ICPC南京网络赛
B.super_log (欧拉降幂) •题意 定一个一个运算log*,迭代表达式为 给定一个a,b计算直到迭代结果>=b时,最小的x,输出对m取余后的值 •思路 $log*_{a}(1)=1+l ...
- 2019icpc南京网络赛_F_Greedy Sequence
题意 题意不明,队友告诉我对于每个\(i\),所在下标\(p[i]\),在\([p[i]-k,p[i]+k]\)中找到小于\(i\)的最大数\(x\),然后\(ans[i]=ans[x]+1\)即可. ...
- 2019icpc南京网络赛 A 主席树
题意 给一个\(n\times n\)的螺旋矩阵,给出其中的\(m\)个点的值分别为各个点上数字的数位之和,给出\(q\)个询问,每次询问从\((x1,y1)\)到\((x2,y2)\)的子矩阵的和. ...
- 2019icpc南京网络赛 F 主席树
题意 给一个\(n\)的全排列数组\(a\),求一个递推数组每一项的值:\(ans[i]=ans[j]+1\),\(j\)为\(a[pos[i]-k]到a[pos[i]+k],(pos[i]为i在数组 ...
随机推荐
- LeetCode 1047. 删除字符串中的所有相邻重复项(Remove All Adjacent Duplicates In String)
1047. 删除字符串中的所有相邻重复项 1047. Remove All Adjacent Duplicates In String 题目描述 LeetCode1047. Remove All Ad ...
- Windows 下升级 node & npm 到最新版本
查询 Node 的安装目录where node 升级 Node:在官网下载最新的安装包,直接安装即可.https://nodejs.org/ 升级 npmnpm install -g npm 使用 n ...
- Python-13-模块和包
一.模块的概念 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代 ...
- Git手册(一):基本操作
Git小册 本手册参考自runoob及其他网络资源,仅用于学习交流 Git工作流程 一般工作流程 1.克隆 Git 资源作为工作目录. 2.在克隆的资源上添加或修改文件. 3.如果其他 ...
- Golang 实现单例模式
目录 只适用于单线程环境 支持并发版本 优化并发版本 sync.Once版本 只适用于单线程环境 package main import "fmt" type Single str ...
- homebrew 使用代理
ALL_PROXY=socks5://127.0.0.1:1086 brew cask install aerial
- Java操作Hadoop集群
mavenhdfsMapReduce 1. 配置maven环境 2. 创建maven项目 2.1 pom.xml 依赖 2.2 单元测试 3. hdfs文件操作 3.1 文件上传和下载 3.2 RPC ...
- jQuery动画(带参数)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- JavaScript之运算符
(1)赋值运算符 // c+=1; // 相当于c=c+1; // console.log(a++); // 先将a的值赋值给表达式,a再加1 // console.log(++a); // a先加1 ...
- 【JUC】5.线程池—Executor
创建线程池可以分为三种方式: 1. 通过ThreadPoolExecutor的构造方法,创建ThreadPoolExecutor的对象,即一个线程池对象: 此构造方法,一共7个参数,5个必须参数,2个 ...