题目链接:https://nanti.jisuanke.com/t/41299
题目大意:
定义这么一种运算,求满足的最小正整数x,求x%m的值
题目思路:
当事人就是痛苦,非常的痛苦!!!!!!尼玛预处理写错了,太丢人了.........................
还是训练强度太弱,不能再这么颓靡了
首先观察这玩意儿,x到0的时候是-1,然后递归回去一层得到0,然后是1,接着是2,然后3.......这样就可以发现,想要让x尽可能小,其实就是a^a^a^a^a...(b个a),实在不放心的小伙伴可以试试,b个a的幂次代进去就是b
然后就是牛B的欧拉降幂
后面两条其实并不需要gcd一定要不为1,只要大小关系符合要求就可以用
所以我的方法是,先预处理出a^a^a^a...中小于1e8的,因为模范围1e6,所以没预处理出来的数一定是大于它模的欧拉函数的,那么也就直接使用最后一条公式,不需要分类讨论,好像跟其他人的写法不太一样,但是我感觉我的更好理解也更不容易错
所以。。。这题我居然错在了,我把底的优先级当成比算幂的优先级高了,结果一直没发现以为是欧拉降幂写错了
知道真相的我眼泪掉下来
以下是代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e6 + 5;
#define rep(i,a,b) for(int i=a;i<=b;i++)
typedef double db;
int euler[maxn];
void get(){
memset(euler,0,sizeof(euler));
euler[1]=1;
for(int i=2;i<maxn;i++){
if(!euler[i]){
for(int j=i;j<maxn;j+=i){
if(!euler[j]){
euler[j]=j;
}
euler[j]=euler[j]/i*(i-1);
}
}
}
}
ll qpow(ll di,ll mi,ll mod)
{
ll ans = 1;
while(mi)
{
if(mi & 1)
ans = ans*di % mod;
di = di*di%mod;
mi>>=1;
}
return ans;
}
int pos;
ll p[maxn];
ll a,b,m;
ll dfs(ll n,ll m){
if(m==1)return 0;
if(n<=pos){
if(p[n]<m)return p[n];
return p[n]%m+m;
}
ll rst=dfs(n-1,euler[m]);
return qpow(a,euler[m],m)*qpow(a,rst,m)%m;
}
int main()
{
get();
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lld%lld%lld",&a,&b,&m);
if(a==1||!b){
printf("%lld\n",1%m);
continue;
}
pos=0;
ll temp=a;
while(pos<b){
p[++pos]=temp;
ll temp2=1;
rep(i,1,temp){
temp2*=a;
if(temp2>=1e8)break;
}
if(temp2>=1e8)break;
temp=temp2;
}
printf("%lld\n",dfs(b,m)%m);
}
return 0;
}