扩展欧拉定理

CF906D Power Tower

洛谷交的第二个黑题

题意

给出一个序列\(w-1,w_2,\cdots,w_n\),以及\(q\)个询问

每个询问给出\(l,r\),求:

\[w_l^{w_{l+1}^{w_{l+2}^{\cdots^{w_r}}}}\bmod p
\]

\(w_i\le 10^9,p\le 10^9,n\le 10^5,q\le 10^5\)


相似题:P4139 上帝与集合的正确用法

都是用欧拉函数,如果你不知道扩展欧拉定理是啥,看这里

和那题一样,递归的处理指数,和\(p\)取模,然后每递归一层,就让\(p\leftarrow \varphi(p)\)

然后这样一层层递归下去,直到\(p=1\)或者\(l=r\)

对于任意一个偶数\(p\),总有\(\varphi(p)\le \dfrac{p}{2}\),因为在小于等于它的数中,一定会有\(\dfrac{p}{2}\)个数是二的倍数,不和他互质

然后又因为对于\(p>2\),总有\(\varphi(p)\)为偶数,原因是当\(\gcd(d,p)=1,\gcd(p-d,p)=1\)(这个可以由反证法很容易的得出)

所以,对于任意一个\(p\),先经过一次给他变成\(\varphi(p)\),然后只要\(\log\)次就可以把它变成\(1\),所以递归最多\(O(\log p)\)层

但是要开一个map来记录已经算出的\(\varphi\),否则\(O(q\log p\sqrt p)\)跑不出来

还有一个问题,就是扩展欧拉定理的应用条件是\(b\ge \varphi(p)\),\(b\)是指数

所以要判断一下\(b\)和\(\varphi(p)\)的大小关系,然而那个上帝与集合的题不用这样,因为那个是无限个\(2\)在指数上,显然\(b>\varphi(p)\)

但是,我们在下一层递归中返回的,已经是对\(\varphi(p)\)取模以后\(b\)的值了,不是真实值,无法比较

如果同时记录真实值和取模后的值又比较麻烦,所以考虑每次取模,都是如果大于等于模数,就让他取模后再加上模数,如果小于模数当然就不管

结束递归回溯的时候也要取模

\(\texttt{code.}\)

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<map>
#define reg register
#define EN std::puts("")
#define LL long long
inline LL read(){
register LL x=0;register int y=1;
register char c=std::getchar();
while(c<'0'||c>'9'){if(c=='-') y=0;c=std::getchar();}
while(c>='0'&&c<='9'){x=x*10+(c^48);c=std::getchar();}
return y?x:-x;
}
int w[100006];
std::map<LL,LL>map;
inline LL get_phi(LL n){
if(map.find(n)!=map.end()) return map[n];
LL ret=n;
for(reg LL i=2;i*i<=n;i++){
if(!(n%i)) ret=ret/i*(i-1);
while(!(n%i)) n/=i;
}
if(n>1) ret=ret/n*(n-1);
map[n]=ret;
return ret;
}
inline LL mo(LL x,LL mod){
return x<mod?x:(x%mod+mod);
}
inline LL power(LL a,LL b,LL mod){
LL ret=1;
while(b){
if(b&1) ret=mo(ret*a,mod);
a=mo(a*a,mod);b>>=1;
}
return ret;
}
LL work(int l,int r,LL p){
if(l==r||p==1) return mo(w[l],p);
return power(w[l],work(l+1,r,get_phi(p)),p);
}
int main(){
LL n=read(),p=read();
for(reg int i=1;i<=n;i++) w[i]=read();
int q=read();while(q--){
int l=read(),r=read();
std::printf("%lld\n",work(l,r,p)%p);
}
return 0;
}

CF906D Power Tower的更多相关文章

  1. 【CodeForces】906 D. Power Tower 扩展欧拉定理

    [题目]D. Power Tower [题意]给定长度为n的正整数序列和模数m,q次询问区间[l,r]累乘幂%m的答案.n,q<=10^5,m,ai<=10^9. [算法]扩展欧拉定理 [ ...

  2. CodeForces - 906D Power Tower(欧拉降幂定理)

    Power Tower CodeForces - 906D 题目大意:有N个数字,然后给你q个区间,要你求每一个区间中所有的数字从左到右依次垒起来的次方的幂对m取模之后的数字是多少. 用到一个新知识, ...

  3. Codeforces 906D Power Tower(欧拉函数 + 欧拉公式)

    题目链接  Power Tower 题意  给定一个序列,每次给定$l, r$ 求$w_{l}^{w_{l+1}^{w_{l+2}^{...^{w_{r}}}}}$  对m取模的值 根据这个公式 每次 ...

  4. Codeforces Round #454 D. Power Tower (广义欧拉降幂)

    D. Power Tower time limit per test 4.5 seconds memory limit per test 256 megabytes input standard in ...

  5. CodeForces 907F Power Tower(扩展欧拉定理)

    Priests of the Quetzalcoatl cult want to build a tower to represent a power of their god. Tower is u ...

  6. [Codeforces]906D Power Tower

    虽说是一道裸题,但还是让小C学到了一点姿势的. Description 给定一个长度为n的数组w,模数m和询问次数q,每次询问给定l,r,求: 对m取模的值. Input 第一行两个整数n,m,表示数 ...

  7. D - Power Tower欧拉降幂公式

    题意:给你一个数组a,q次查询,每次l,r,要求 \(a_{l}^{a_{l+1}}^{a_{l+2}}...{a_r}\) 题解:由欧拉降幂可知,最多log次eu(m)肯定变1,那么直接暴力即可,还 ...

  8. Codeforces 906 D. Power Tower

    http://codeforces.com/contest/906/problem/D 欧拉降幂 #include<cstdio> #include<iostream> usi ...

  9. [CodeForces - 906D] Power Tower——扩展欧拉定理

    题意 给你 $n$ 个 $w_i$ 和一个数 $p$,$q$个询问,每次询问一个区间 $[l,r] $,求 $w_l ^{w_{l+1}^{{\vdots}^{w_r}}} \ \% p$ 分析 由扩 ...

随机推荐

  1. 基础类封装-Requests库封装

    #!/usr/bin/env python3 # -*- coding: utf-8 -*- # @Time : 2020/03/18 23:37 # @Author : Tang Yiwei # @ ...

  2. JQUERY滚动加载

    $(document).height():整个网页的高度$(window).height():浏览器可视窗口的高度$(window).scrollTop():浏览器可视窗口顶端距离网页顶端的高度(垂直 ...

  3. BMI的Python实现

    str1 = float(input('请输入您的身高(单位:米):')) # input默认转化为字符串型 用float转化为浮点型 str2 = float(input('请输入您的体重(单位:千 ...

  4. vue-cli3 按需引入 element-ui 报错

    报错信息: Cannot find module 'babel-preset-es2015' from .... 解决办法: 安装最新的 Babel 编译插件:@babel/preset-env 修改 ...

  5. F - Make It Equal CodeForces - 1065C

    题目大意:有n座塔,塔高h[i],每次给定高度H对他们进行削切,要求每次削掉的所有格子数不能超过k个,输出最少削几次才能使所有塔的高度相同. 思路一:差分+贪心 对于每一个高度h,用一个数组让1~h的 ...

  6. [转+自]disable_functions之巧用LD_PRELOAD突破

    写在前面: 通过知乎的一篇艰难的渗透提权,引发了一些对于disable_funcionts绕过的思考,虽然在暑假日记中记载了四种绕过disable_functions,比如com组件,pcntl_ex ...

  7. [整理]svn常见问题汇总

    1.’.’ is not a working copy.Can’t open file‘.svn/entries’: 系统找不到指定的路径.解答:原因是输入的访问路径不正确,如svn://192.16 ...

  8. pytorch中的前项计算和反向传播

    前项计算1 import torch # (3*(x+2)^2)/4 #grad_fn 保留计算的过程 x = torch.ones([2,2],requires_grad=True) print(x ...

  9. /uesr/local/hadoop/tmp/mapred有锁

    原因:  /usr/local/hadoop/tmp/mapred  有锁 解决:修改改文件的权限 在终端输入: cd /usr/local/hadoop/tmp sudo chmod 777 map ...

  10. Xshell下载和连接Linux

    Xshell下载和连接Linux 第一步.Xshell的下载 方法1:从官网下载个人使用时免费的,商业使用是要收费的. http://www.xshellcn.com/ 方法二2:百度云下载Xshel ...