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在数组 ...
随机推荐
- java 模拟多ip访问
java模拟多ip请求 package url_demo; import java.io.BufferedReader; import java.io.IOException; import java ...
- Connection to api@localhost failed. [08001] Could not create connection to d
pycharm 换成2019之后连接数据库用户名密码数据库名字都没错,就是连接不上去,网上百度一下,试试将URL后面拼接 ?useSSL=false&serverTimezone=UTC 发现 ...
- SQL——BETWEEN操作符
一.BETWEEN操作符的基本用法 BETWEEN操作符用于选取两个值范围内的值. 语法格式如下: SELECT 列名1,列名2... FROM 表名 WHERE 列名 BETWEEN 值1 AND ...
- PAT(B) 1035 插入与归并(Java)
题目链接:1035 插入与归并 (25 point(s)) 参考博客:PAT乙级--1035(插入排序和归并)java实现熊仙森 题目描述 根据维基百科的定义: 插入排序是迭代算法,逐一获得输入数据, ...
- 不一样的go语言-athens源码概览
前言 上一篇文章介绍了athens私服的安装以及vgo download protocol的简要介绍.本文着重介绍go proxy sever的实现原理以及athens是如何实现的. go get ...
- 协议——VGA
VGA(Video Graphics Array)是IBM在1987年随PS/2机一起推出的一种视频传输标准,具有分辨率高.显示速率快.颜色丰富等优点,在彩色显示器领域得到了广泛的应用.不支持热插拔, ...
- gitlab 安装、备份与还原及常见设置
gitlab 安装.备份与还原及常见设置 安装 安装过程比较简单,跑在 docker 上,执行命令即可 -v参数后面的值为卷的名称,自动创建数据卷(如果数据卷不存在) https://docs.git ...
- Codeforces 1207 G. Indie Album
Codeforces 1207 G. Indie Album 解题思路 离线下来用SAM或者AC自动机就是一个单点加子树求和,套个树状数组就好了,因为这个题广义SAM不能存在 \(len[u] = l ...
- 常用的MySQL命令
1.新建数据库: create database person; 2.使用数据库 use person: 3.创建一个表格 create table student ( id int(10) not ...
- element-ui 默认排序
table属性中,设置 :default-sort="{prop:'time', order:'descending'}" 1. prop为排序列,order为排列顺序 2. 多级 ...