这里我们定义 \varphi(n)φ(n) 表示所有小于等于 nn 与 nn 互质数的个数。
例如 \varphi(10) = 4φ(10)=4,因为我们可以在 1 \sim 101∼10 中找到 1,3,7,91,3,7,9 与 1010 互质。
输入格式
第一行输入一个整数 tt,表示测试数据组数。
接下来 tt 行,每行有一个整数 nn。
输出格式
对于每组测试数据输出 \varphi(n)φ(n) 。
数据范围
1 \le t \le 100, 1 \le n \le 10^{10}1≤t≤100,1≤n≤1010。
Sample Input
3 2 10 100
Sample Output
1 4 40
这道题会做但是一个超内存一个超时长。
#include<stdio.h>
int gad(int a,int b){
return b==0?a:gad(b,a%b);//与取得最小公倍数很像
}
int main()
{
int n,pan;
int ans;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
ans=0;
scanf("%d",&pan);
for(int j=1;j<pan;j++){
if(gad(j,pan)==1){
ans++;
}
}
printf("%d\n",ans);
}
return 0;
}
这个会是时间超限
#include<stdio.h>
#include<math.h>
#include<string.h>
int per(int x,int n);
void huzhi(int n );
void yin(int n);
int ans,a[100000000];
void huzhi(int n){
for(int i=2;i<n;i++){
if(n%i==0){
continue;
}else{
if(per(i,n)){
ans++;
}
}
}
}
int per(int x,int n){
int m=1;
for(int i=2;i<=sqrt(n);i++){
if(a[i]>0){
if(x%i==0){
m=0;
}
}
}
return m;
}
void yin(int n){
for(int i=2;i<=sqrt(n);i++){
if(n%i==0){
a[i]++;
}
}
}
int main()
{
int n,pan;
scanf("%d",&n);
for(int i=0;i<n;i++){
ans=1;
scanf("%d",&pan);
yin(pan);
huzhi(pan);
printf("%d\n",ans);
memset(a,0,sizeof(a));
}
return 0;
}
没写注释可能很难理解,这是我写的最笨的方法,是空间超限
接下来是我大哥(一个童鞋)写的
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstdio>
#include<sstream>
#include<bitset>
#include<algorithm>
#include<cctype>
#include<map>
#include<queue>
#include<set>
#include<vector>
#include<functional>
#include<cstring>
#include<stack>
#include<unordered_set>
using namespace std;
typedef long long ll;
ll oula(ll n)
{
ll res = n;
for (ll i = 2; i <= sqrt(n); i++)
{
if (n % i == 0)
{
res = res / i * (i - 1);
while (n % i == 0)
n /= i;
}
}
if (n != 1)
res = res / n * (n - 1);
return res;
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
ll n;
scanf("%lld", &n);
cout << oula(n);
cout << '\n';
}
return 0;
}