扩展欧拉定理
AC代码
bzoj 3884
#include<bits/stdc++.h>
#define N 2000005
#define P pair<int,int>
using namespace std;
typedef long long ll;
const int M=1e9+7;
const int MM=1e9+6;
const int inf=1e9+7;
ll Mod(ll x,ll y){
return x < y ? x : x % y + y;
}
long long phi(long long n)
{
ll m = sqrt(n+0.5);
ll ans = n;
for(int i=2; i<=m; ++i) if(n%i == 0)
{
ans = ans/i * (i-1);
while(n%i == 0) n /= i;
}
if(n > 1) ans = ans/n * (n-1);
return ans;
}
ll quick(ll a,ll b,int mod)
{
ll c=1;
while(b){
if(b&1)c=Mod(c*a,mod);
a=Mod(a*a,mod);
b>>=1;
}
return c;
}
ll solve(int p)
{
//printf(" %d\n",p);
if(p==1)return 1;
ll ans=solve(phi(p));
return quick(2,ans,p);
}
int main()
{
int t;
for(scanf("%d",&t);t;t--)
{
int p;
scanf("%d",&p);
printf("%lld\n",solve(p)%p);
}
return 0;
}
Codeforces 906D
#include<bits/stdc++.h>
#define N 2000005
#define P pair<int,int>
using namespace std;
typedef long long ll;
const int M=1e9+7;
const int MM=1e9+6;
const int inf=1e9+7;
ll Mod(ll x,ll y){
return x < y ? x : x % y + y;
}
long long phi(long long n)
{
ll m = sqrt(n+0.5);
ll ans = n;
for(int i=2; i<=m; ++i) if(n%i == 0)
{
ans = ans/i * (i-1);
while(n%i == 0) n /= i;
}
if(n > 1) ans = ans/n * (n-1);
return ans;
}
ll quick(ll a,ll b,int mod)
{
ll c=1;
while(b){
if(b&1)c=Mod(c*a,mod);
a=Mod(a*a,mod);
b>>=1;
}
return c;
}
int w[N];
vector<int>p;
ll solve(int l,int r,int d)
{
if(d==p.size())return 1;
if(l==r)return w[l]<p[d]?w[l]:w[l]%p[d]+p[d];
ll ans=solve(l+1,r,d+1);
return quick(w[l],ans,p[d]);
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int t=m;
do{
p.push_back(t);
t=phi(t);
}while(t!=1);
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
int q;
for(scanf("%d",&q);q;q--)
{
int l,r;
scanf("%d%d",&l,&r);
printf("%lld\n",solve(l,r,0)%m);
}
return 0;
}