CF906DPower Tower
Posted stoorz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF906DPower Tower相关的知识,希望对你有一定的参考价值。
题目
题目链接:https://codeforces.com/problemset/problem/906/D
给出一个数列 (a),每次询问给出 (l,r),求
思路
根据扩展欧拉定理,当 (bgeq varphi(p)) 时,
[a^bequiv a^{bmod varphi(p)+varphi(p)}pmod p
]
所以我们可以考虑递归求解,类似 这题,直到 (l>r) 或 (p=1)。
由于 (varphi(varphi(n))...) 在 (log n) 次就会下降至 1,所以递归求解时间复杂度 (O(nlog n))。
但是这题 (pleq 10^9),线性筛显然不行,考虑到只有 (O(nlog n)) 个数要求 (varphi),所以直接每个数暴力求 (varphi),然后套上记忆化优化一下即可。
时间复杂度 (O(nsqrt{n}log n))。而且远远跑不满。
代码
#include <map>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N=100010;
int n,Q,MOD,a[N];
map<int,int> phi;
int Phi(int x)
{
if (phi[x]) return phi[x];
int p=x,y=x;
for (int i=2;i*i<=x;i++)
if (x%i==0)
{
p=p/i*(i-1);
while (x%i==0) x/=i;
}
if (x>1) p=p/x*(x-1);
return phi[y]=p;
}
ll fpow(ll x,ll k,int mod)
{
ll ans=1;
for (;k;k>>=1,x*=x)
{
if (x>=mod) x=x%mod+mod;
if (k&1) ans=ans*x;
if (ans>=mod) ans=ans%mod+mod;
}
return ans;
}
int solve(int x,int y,int p)
{
if (p==1 || x>y) return 1;
return (int)fpow(a[x],solve(x+1,y,Phi(p)),p);
}
int main()
{
scanf("%d%d",&n,&MOD);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
scanf("%d",&Q);
while (Q--)
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d
",solve(l,r,MOD)%MOD);
}
return 0;
}
以上是关于CF906DPower Tower的主要内容,如果未能解决你的问题,请参考以下文章
CodeForces - 906D Power Tower(欧拉降幂定理)
[CodeForces - 906D] Power Tower——扩展欧拉定理
CodeForces906 D. Power Tower 扩展欧拉定理