[模板]欧拉函数及其应用

什么是欧拉函数?

   欧拉函数是小于x的整数中与x互质的数的个数,一般用φ(x)表示。特殊的,φ(1)=1。


https://blog.csdn.net/liuzibujian/article/details/81086324

埃拉托斯特尼筛求欧拉函数
时间O(√n)
空间O(1)
ll getphi(ll x)
{
    ll ans = x;
    for(ll i = 2; i * i <= x; i++)
        if(x % i == 0)
        {
            ans -= ans / i;
            while(x % i == 0)   x /= i;
        }
    if(x > 1) ans -= ans / x;
    return ans;
}


欧拉筛求欧拉函数

void euler(int n)
{
	phi[1]=1;//1要特判 
	for (int i=2;i<=n;i++)
	{
		if (flag[i]==0)//这代表i是质数 
		{
			prime[++num]=i;
			phi[i]=i-1;
		}
		for (int j=1;j<=num&&prime[j]*i<=n;j++)//经典的欧拉筛写法 
		{
			flag[i*prime[j]]=1;//先把这个合数标记掉 
			if (i%prime[j]==0)
			{
				phi[i*prime[j]]=phi[i]*prime[j];//若prime[j]是i的质因子,则根据计算公式,i已经包括i*prime[j]的所有质因子 
				break;//经典欧拉筛的核心语句,这样能保证每个数只会被自己最小的因子筛掉一次 
			}
			else phi[i*prime[j]]=phi[i]*phi[prime[j]];//利用了欧拉函数是个积性函数的性质 
		}
	}
}

欧拉函数降幂

/*
    Zeolim - An AC a day keeps the bug away
*/

//#pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <sstream>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
typedef long long ll;
typedef long double ld;
const int INF = 0x3f3f3f3f;
const ld PI = acos(-1.0);
const ld E = exp(1.0);
const ll mod = 1e9 + 7;
const int MAXN = 1e6 + 10;

ll qpow(ll a, ll b, ll mod)
{
    ll ret = 1;
    while(b)
    {
        if(b & 1)
            ret = ret * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ret % mod;
}


ll getphi(ll x)
{
    ll ans = x;
    for(ll i = 2; i * i <= x; i++)
        if(x % i == 0)
        {
            ans -= ans / i;
            while(x % i == 0)   x /= i;
        }
    if(x > 1) ans -= ans / x;
    return ans;
}

int main()
{
    //ios::sync_with_stdio(false);
    //cin.tie(0);     cout.tie(0);
    //freopen("D://test.in", "r", stdin);
    //freopen("D://test.out", "w", stdout);
    
    string s;

    ll phi = getphi(mod);

    while(cin >> s && s != "0")
    {
        if(s == "1")
        {
            cout << "2" << '
';
            continue;
        }

        else
        {
            int x = s.length() - 1;

            if(s[x] != '0')
            {
                --s[x];
            }
            else
            {
                while(s[x] == '0')
                {
                    s[x] = '9';
                    --x;
                }
                --s[x];
            }
        }

        ll b = 0;

        for(int i = 0; i < s.length(); ++i)
            b = (b * 10 + s[i] - '0') % phi;
       
        b += phi;
       
        ll ans = 0;

        ans = (qpow(2, b, mod) + qpow(4, b, mod)) % mod;
        cout << ans << '
';
    }

    return 0;
}
原文地址:https://www.cnblogs.com/zeolim/p/12270409.html