#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
while(n--)
{
int x;
cin>>x;
int res=x;
for(int i=2;i<=x/i;i++)
{
if(x%i==0)
{
res=res/i*(i-1);
while(x%i==0) x/=i;
}
}
if(x>1) res=res/x*(x-1);
cout<<x<<endl;
}
}
/*
如果用上道题做法,对每个数直接用公式求解,对每个数都要分解质因数,时间复杂度是n*sqrt(n)
可以用线性筛法用O(n)时间复杂度顺便求出每个数的欧拉函数
线性筛法可以顺便求出来很多东西
用处:欧拉定理
若a与n互质,则a^(n的欧拉函数)模n等于1
推论:当n是质数时 a^(n-1)模n等于1 费马定理
*/
#include <iostream>
using namespace std;
typedef long long LL;
const int N = 1000010;
int primes[N], cnt;
int euler[N];
bool st[N];
void get_eulers(int n)
{
euler[1] = 1;
for (int i = 2; i <= n; i ++ )
{
if (!st[i])//如果当前这个数没有被筛过,说明i是一个质数
{
primes[cnt ++ ] = i;
euler[i] = i - 1;//质数i的欧拉函数就是i-1
}
for (int j = 0; primes[j] <= n / i; j ++ )
{
int t = primes[j] * i;
st[t] = true;
if (i % primes[j] == 0)
{
/*
求欧拉函数过程中,只有这个数包含某个质因子,就乘(1-1/pj),与这个质因子的次数没有关系
比如6的欧拉函数==6*(1-1/2)(1-1/3)
另外一个数n==2^100 * 3^100,它的欧拉函数==n*(1-1/2)(1-1/3),和次数无关
primes[j] * i的欧拉函数与i的欧拉函数的关系:
当i % primes[j] == 0时,primes[j]是i的最小质因子,也是primes[j] * i的最小质因子,
所以primes[j] * i与i的质因子是相同的,所以euler[primes[j] * i] = euler[i] * primes[j]
当i % primes[j] != 0时,primes[j]小于i的最小质因子,是primes[j] * i的最小质因子,
euler[primes[j] * i] == euler[i] * primes[j] * (primes[j] - 1) / primes[j]
== euler[i] * (primes[j] - 1)
*/
euler[t] = euler[i] * primes[j];
break;
}
euler[t] = euler[i] * (primes[j] - 1);
}
}
}
int main()
{
int n;
cin >> n;
get_eulers(n);
LL res = 0;//和可能很大,会报int,所以用ll来存
for (int i = 1; i <= n; i ++ ) res += euler[i];
cout << res << endl;
return 0;
}
/*
快速求出来 a^k mod p,时间复杂度 O(logk)
核心思路是反复平方,预处理出来a^(2^0) mod p,a^(2^1) mod p,...a^(2^logk) mod p
把a^k mod p 拆成前面预处理的logk个数的乘积,k转换成二进制
*/
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
LL qmi(int a, int b, int p)
{
LL res = 1 % p;
while (b)
{
if (b & 1) res = res * a % p;//凡是中间结果可能会溢出的地方,都要特殊处理
a = a * (LL)a % p;
//a * (LL)a % p和(LL)a * a % p 第2个的a∗p可能爆int,所以(LL)写到中间是个好习惯
b >>= 1;//删掉最后一位
}
return res;
}
int main()
{
int n;
cin>>n;
while (n -- )
{
int a, b, p;
cin>>a>>b>>p;
cout<<qmi(a, b, p)<<endl;
}
return 0;
}
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
LL qmi(int a, int b, int p)
{
LL res = 1;
while (b)
{
if (b & 1) res = res * a % p;
a = a * (LL)a % p;
b >>= 1;
}
return res;
}
int main()
{
int n;
cin>>n;
while (n -- )
{
int a, p;
cin>>a>>p;
if (a % p == 0) puts("impossible");// a是p的倍数时无解
else cout<<qmi(a, p - 2, p)<<endl;
}
return 0;
}
/*
求x, y,使得ax + by = gcd(a, b)
裴蜀定理
对于任意正整数a,b 那么一定存在非零整数x,y使得ax + by = gcd(a, b)
如果ax + by = d 则d一定是gcd(a, b)的倍数
*/
#include <iostream>
#include <algorithm>
using namespace std;
/*
int gcd(int a, int b)
{
if (!b)
{
return a;
}
return gcd(b, a % b);
}
*/
int exgcd(int a, int b, int &x, int &y)//后两者传引用
{
if (!b)
{
x = 1, y = 0;
return a;
}
int d = exgcd(b, a % b, y, x);
y -= a / b * x;//x不变,y-= a / b * x
return d;
}
int main()
{
int n;
cin>>n;
while (n -- )
{
int a, b;
cin>>a>>b;
int x, y;
exgcd(a, b, x, y);
cout<<x<<' '<<y<<endl;
}
return 0;
}
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
int exgcd(int a, int b, int &x, int &y)
{
if (!b)
{
x = 1, y = 0;
return a;
}
int d = exgcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
int main()
{
int n;
cin>>n;
while (n -- )
{
int a, b, m;
cin>>a>>b>>m;
int x, y;
int d = exgcd(a, m, x, y);//扩展欧几里得算法求出最大公约数d
if (b % d) puts("impossible");//b能够整除最大公约数d有解
else cout<<(LL)b / d * x % m<<endl;//x扩大若干倍模到m范围内即可
}
return 0;
}
/*
推导见
https://www.acwing.com/solution/content/3539/
https://www.acwing.com/solution/content/23099/
*/
#include<iostream>
using namespace std;
typedef long long LL;//数据范围比较大,所以用LL来存储
LL exgcd(LL a,LL b,LL &x,LL &y)
{
if(!b)
{
x=1,y=0;
return a;
}
LL d=exgcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
int main()
{
int n;
LL a1,m1;
cin>>n>>a1>>m1;
LL x=0;
for(int i=1;i<n;i++)
{
LL a2,m2;
cin>>a2>>m2;
LL k1,k2;
LL d=exgcd(a1,a2,k1,k2);
if((m2-m1)%d)//无解
{
x=-1;
break;
}
k1*=(m2-m1)/d;
//因为此时k1是k1*a1+k2*a2=d的解,所以要乘上(m2-m1)/d的倍数大小
LL t=abs(a2/d);
k1=(k1%t+t)%t;
//数据比较极端,所以只求k的最小正整数解
m1=k1*a1+m1;
//m1在被赋值之后的值为当前"x"的值,此时赋值是为了方便下一轮的继续使用
a1=abs(a1*a2/d);
//循环结束时a1的值为当前所有的a1,a2,……an中的最小公倍数
}
if(x!=-1) x=(m1%a1+a1)%a1;
//当循环结束时,此时的值应该与最小公倍数取模,以求得最小正整数解
cout<<x<<endl;
return 0;
}