1. 程式人生 > >bzoj 3884 上帝與集合的正確用法 Codeforces 906D:Power Tower (擴充套件尤拉定理)

bzoj 3884 上帝與集合的正確用法 Codeforces 906D:Power Tower (擴充套件尤拉定理)

擴充套件尤拉定理

 

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;
}