Generalized Euler's theorem + play table - Last Digits (POJ2720)

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/weixin_42557561/article/details/100041730

Portal


Analysis

Well. . . .
Descending recursively looks pretty, pretty easy
hhhh ...... time to make life difficult

The original play table also records (sets of data)
because the index does not necessarily meet the prime to the modulus, so when descending to Category talk (the index is greater than φ (mod))
due to the direct discussions do not know how to do
it ... ... 1e7 play table below figure out
the rest of the discussion can be


Code
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#include<iomanip>
#define int long long
#define re register
using namespace std;
typedef long long ll;
int base[10]={1, 10, 100, 1000, 10000, 100000, 1000000, 10000000};
int tab[105][105];
int fxb[105][105];
inline int limit_power(int a,int b){
	ll res=1;
	for(re int i=1;i<=b;++i){
		res=res*1ll*a;
		if(res>1e7) return -1;
	}
	return res;
}
void init(){
	memset(tab,-1,sizeof(tab));
	memset(fxb,-1,sizeof(fxb));
	for(re int i=1;i<=100;++i){
		tab[i][0]=fxb[i][0]=1;
		for(re int j=1;j<=100;++j){/////
			tab[i][j]=fxb[i][j]=limit_power(i,fxb[i][j-1]);
			if(tab[i][j]==-1) break;
		}
	}
}
inline ll ksm(int x,int b,int mod){
	ll res=1;
	while(b){
		if(b&1) res=res*x%mod;
		x=x*x%mod;
		b>>=1;
	}
	return res;
}
inline int get_phi(int x){
	int ans=x;
	for(re int i=2;i*i<=x;++i){
		if(x%i==0){
			ans=ans/i*(i-1);
			while(x%i==0) x/=i;
		}
	}
	if(x>1) ans=ans/x*(x-1);
	return ans;
}
int solve(int b,int a,int mod){
	if(fxb[b][a]!=-1) return fxb[b][a]%mod;//
	int phi=get_phi(mod);
	if(fxb[b][a-1]!=-1&&fxb[b][a-1]<=phi)
		return ksm(b,fxb[b][a-1],mod);
	return ksm(b,solve(b,a-1,phi)+phi,mod);
}
signed main(){
	int b,x,n;
	init();
	while(1){
		scanf("%lld",&b);
		if(!b) return 0;
		scanf("%lld%lld",&x,&n);
		int res;
		if(tab[b][x]==-1){
			tab[b][x]=solve(b,x,1e7);
			res=tab[b][x]%base[n];
		}
		else res=tab[b][x]%base[n];
		cout<<setfill('0')<<setw(n)<<res<<'\n';
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_42557561/article/details/100041730