zoukankan      html  css  js  c++  java
  • 【CF906D】Power Tower

    题目

    题目链接:https://codeforces.com/problemset/problem/906/D
    给出一个数列 \(a\),每次询问给出 \(l,r\),求

    思路

    根据扩展欧拉定理,当 \(b\geq \varphi(p)\) 时,

    \[a^b\equiv a^{b\bmod \varphi(p)+\varphi(p)}\pmod p \]

    所以我们可以考虑递归求解,类似 这题,直到 \(l>r\)\(p=1\)
    由于 \(\varphi(\varphi(n))...\)\(\log n\) 次就会下降至 1,所以递归求解时间复杂度 \(O(n\log n)\)
    但是这题 \(p\leq 10^9\),线性筛显然不行,考虑到只有 \(O(n\log n)\) 个数要求 \(\varphi\),所以直接每个数暴力求 \(\varphi\),然后套上记忆化优化一下即可。
    时间复杂度 \(O(n\sqrt{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\n",solve(l,r,MOD)%MOD);
    	}
    	return 0;
    }
    
  • 相关阅读:
    PHP面向对象之原型(trait)
    PHP面向对象之命名空间
    Javascript中的Copy()函数
    六、unique_lock取代lock_guard
    五、互斥量
    四、创建和等待多个线程
    三、线程传参
    二、线程的启动与结束 join与detach
    HTTP:常见状态码
    HTTP:简述URL、URN和URI
  • 原文地址:https://www.cnblogs.com/stoorz/p/12604597.html
Copyright © 2011-2022 走看看