1. 程式人生 > 其它 >Robot Framework自定義測試庫開發詳解

Robot Framework自定義測試庫開發詳解

原題傳送門

題意:\(T\)組資料,對於每個模數\(p\),求\(2^{2^{2^{...}}} mod\) \(p\)\(T\le 10^3\)\(p\le 10^7\)

思路:擴充套件尤拉定理
顯然\({2^{2^{...}}}\)這個無限數,是大於\(\varphi(p)\)的,那麼由擴充套件尤拉定理可得:
對於\(b\ge \varphi(p)\)
\(a^b\equiv a^{b\ mod\ \varphi(p)+\varphi(p)}\ mod\ p\)
很顯然這個是遞迴式子,模數\(\varphi(p)\)很快會降為\(1\),此時式子為\(0\)
對於\(\varphi(p)\)

,我們可以用線性篩預處理得到
時間複雜度:\(O(p+Tlog\ p)\)

接下來我們談一下,如何用線性篩預處理尤拉函式\(\varphi(x)\)
對於\(\varphi(x)\)我們利用如下性質:

  • \(\varphi(x)=x-1\)\(x\in prime\)
  • \(\varphi(x^k)=x^k-x^{k-1}\)\(x\in prime\)
  • \(gcd(m,n)=1\),\(\varphi(mn)=\varphi(m) \varphi(n)\)

由此,我們得到尤拉函式是個積性函式,而線性篩可以預處理積性函式
Code

bool vis[N];
int cnt,prime[N/10],phi[N],p,t;
void get_phi(int n){
	phi[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i]){
			prime[++cnt]=i;
			phi[i]=i-1;
		}
		for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
			vis[i*prime[j]]=1;
			if(i%prime[j]==0){
				phi[i*prime[j]]=phi[i]*prime[j];
				break;
			}
			else phi[i*prime[j]]=phi[i]*(prime[j]-1);
		}
	}
}

套用這個模板,本題就很容易了
Code

#include <bits/stdc++.h>
using namespace std;
const int N=1e7+10;
typedef long long ll;
bool vis[N];
int cnt,prime[N/10],phi[N],p,t;
void get_phi(int n){
	phi[1]=1;
	for(int i=2;i<=n;i++){
		if(!vis[i]){
			prime[++cnt]=i;
			phi[i]=i-1;
		}
		for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
			vis[i*prime[j]]=1;
			if(i%prime[j]==0){
				phi[i*prime[j]]=phi[i]*prime[j];
				break;
			}
			else phi[i*prime[j]]=phi[i]*(prime[j]-1);
		}
	}
}
int power(int a,int b,int p){
	int res=1;
	for(;b;b>>=1){
		if(b&1) res=1LL*res*a%p;
		a=1LL*a*a%p;
	}
	return res;
}
int solve(int x){
	if(x==1) return 0;
	return power(2,solve(phi[x])+phi[x],x);
}
int main(){
	get_phi(N);
	cin>>t;
	while(t--){
		cin>>p;
		cout<<solve(p)<<endl;
	}
	return 0;
}