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 扩展欧拉定理

CodeForces 906D Power Tower <<欧拉降幂

CF906EReverses(回文自动机,最小回文分割)

CF392B Tower of Hanoi