UVa 10837 (欧拉函数 搜索) A Research Problem

发现自己搜索真的很弱,也许做题太少了吧。代码大部分是参考别人的,=_=||

题意:

给出一个phi(n),求最小的n

分析:

回顾一下欧拉函数的公式:,注意这里的Pi是互不相同的素数,所以后面搜索的时候要进行标记。

先找出所有的素数p,满足(p - 1)整除题目中所给的phi(n)

然后暴搜。。

素数打表打到1e4就够了,如果最后剩下一个大素数单独进行判断。

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6
 7 const int maxn = 10000;
 8 const int INF = 200000000;
 9
10 int phi_n, ans;
11
12 bool vis[maxn + 10];
13 int prime[1500], pcnt = 0;
14 int fac[1500], tot;
15
16 void prime_table()
17 {
18     int m = sqrt(maxn + 0.5);
19     for(int i = 2; i <= m; i++) if(!vis[i])
20         for(int j = i * i; j <= maxn; j += i) vis[j] = true;
21     for(int i = 2; i <= maxn; i++) if(!vis[i]) prime[pcnt++] = i;
22 }
23
24 void factor(int n)
25 {
26     tot = 0;
27     for(int i = 0; i < pcnt && (prime[i]-1) * (prime[i]-1) <= n; i++) if(n % (prime[i] - 1) == 0)
28         fac[tot++] = prime[i];
29 }
30
31 int judge(int n)
32 {
33     if(n == 1) return 1;
34     n++;
35     //判断剩余的phin中加1后是否为素数
36     for(int i = 0; i < pcnt && prime[i] * prime[i] <= n; i++) if(n % prime[i] == 0)
37         return -1;
38     //如果为素数的话,判断是否标记过
39     for(int i = 0; i < tot; i++) if(vis[i] && n == fac[i])
40         return -1;
41     return n;
42 }
43
44 void dfs(int n, int phin, int d)
45 {
46     if(d == tot)
47     {
48         int t = judge(phin);
49         if(t > 0) ans = min(ans, n * t);
50         return;
51     }
52
53     dfs(n, phin, d+1);
54     if(phin % (fac[d] - 1) == 0)
55     {
56         vis[d] = true;
57         n *= fac[d];
58         phin /= (fac[d] - 1);
59         for(;;)
60         {
61             dfs(n, phin, d+1);
62             if(phin % fac[d] != 0)
63                 return;
64             phin /= fac[d]; n *= fac[d];
65         }
66     }
67     vis[d] = false;
68 }
69
70 int main()
71 {
72     freopen("in.txt", "r", stdin);
73
74     int kase = 0;
75     prime_table();
76     while(scanf("%d", &phi_n) == 1 && phi_n)
77     {
78         ans = INF;
79         memset(vis, false, sizeof(vis));
80         factor(phi_n);
81         dfs(1, phi_n, 0);
82         printf("Case %d: %d %d\n", ++kase, phi_n, ans);
83     }
84
85     return 0;
86 }

代码君

时间: 2024-09-30 10:27:19

UVa 10837 (欧拉函数 搜索) A Research Problem的相关文章

A Research Problem UVA - 10837 欧拉函数逆应用

平时看到的题目是给n求phi(n) 现在是给phi(n)求一个最小n 当一个数为素数是m=n*(1-1/n); 例如 12=13(1-1/13);所以可以得出 m%(n-1)==0 时,n-1为n的素因子 m=n*(1-1/p1)*(1-1/pn); n=p1^x1*(p1-1)*p2^x2(p2-1)......; #include <iostream> #include <stdio.h> #include <cmath> #include <algorith

UVa 11440 (欧拉函数) Help Tomisu

题意: 给出N和M,统计区间x ∈ [2, N!],x满足所有素因子都大于M的x的个数. 分析: 首先将问题转化一下,所有素因子都大于M 等价于 这个数与M!互素 对于k大于M!,k与M!互素等价于 k % M! 与 M!互素 所以我们可以求出φ(M!)(φ为欧拉函数) 然后乘以N! / M!,最后答案再减一(因为是从2开始统计的) 欧拉函数的公式为a phifac[n] = φ(n!),我们递推求phifac 当n为合数时,n!和(n-1)!的素因数的集合是一样的,所以phifac[n] =

UVa 11426 (欧拉函数 GCD之和) GCD - Extreme (II)

题意: 求sum{gcd(i, j) | 1 ≤ i < j ≤ n} 分析: 有这样一个很有用的结论:gcd(x, n) = i的充要条件是gcd(x/i, n/i) = 1,因此满足条件的x有phi(n/i)个,其中Phi为欧拉函数. 所以枚举i和i的倍数n,累加i * phi(n/i)即可. 1 #include <cstdio> 2 typedef long long LL; 3 4 const int maxn = 4000000; 5 6 int phi[maxn + 10]

UVA - 10820欧拉函数的应用

这是一道很基础的欧拉函数的题目 题意要求  (x,y) 互质 &&x<=n&&y<=n 求互质对数 可以运用容斥,求出 phi(n)=n(1-1/n1)(1-1/n2)......(1-1/nk); 因为(2,4) (4,2) 算两对,所以 答案为 2*f(n)+1; #include<stdio.h> #include<string.h> #include<stdlib.h> #include<iostream>

UVA 11426 (欧拉函数&amp;&amp;递推)

题意:给你一个数N,求N以内和N的最大公约数的和 解题思路: 一开始直接想暴力做,4000000的数据量肯定超时.之后学习了一些新的操作. 题目中所要我们求的是N内gcd之和,设s[n]=s[n-1]+gcd(1,n)+gcd(2,n)+gcd(3,n)+gcd(4,n)....... 再设f[n]=gcd(1,n)+gcd(2,n)+gcd(3,n)+gcd(4,n).......; 思考一下,假设gcd(x,n)=ans,ans便是x和n的最大公约数,那么有几个ans我们将某ans的个数su

UVA 10837 - A Research Problem(欧拉函数)

UVA 10837 - A Research Problem 题目链接 题意:给定phi(n),求最小满足的最小的n 思路:phi(n)=pk11(p1?1)?pk22(p2?1)?pk33(p3?1)....(p为质数),因此对于给定phi(n),先把满足条件phi(n)%(p?1)=0的素数全找出来,在这些素数基础上进行暴力搜索,枚举哪些素数用与不用,求出最小值.这样做看似时间复杂度很高,但是实际上,由于每次多选一个素数之后对于值是呈指数上升的,所以实际组合出来的情况并不会太多,因此是可行的

uva 10837 - A Research Problem(欧拉函数+暴力)

题目链接:uva 10837 - A Research Problem 题目大意:给定一个phin,要求一个最小的n,欧拉函数n等于phin 解题思路:欧拉函数性质有,p为素数的话有phip=p?1;如果p和q互质的话有phip?q=phip?phiq 然后根据这样的性质,n=pk11(p1?1)?pk22(p2?1)???pkii(pi?1),将所有的pi处理出来,暴力搜索维护最小值,虽然看上去复杂度非常高,但是因为对于垒乘来说,增长非常快,所以搜索范围大大被缩小了. #include <cs

uva 11317 - GCD+LCM(欧拉函数+log)

题目链接:uva 11317 - GCD+LCM 题目大意:给定n,求出1~n里面两两的最大公约的积GCD和最小公倍数的积LCM,在10100进制下的位数. 解题思路:在n的情况下,对于最大公约数为i的情况又phi[n/i]次.求LCM就用两两乘积除以GCD即可. #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; ty

UVA 11440 - Help Tomisu(欧拉函数)

UVA 11440 - Help Tomisu 题目链接 题意:给定n和m,求[2,n!]中,所有质因子个数都大于m的个数 思路:?(m!)表示小于m!并与m!互质的个数,而与m!互质的个数,他的质因子肯定不包含1-m,因此就是满足条件的.然后对于这题而言,则是要求n!中,不与m!互质的个数,答案取模100000007 那么先看一个证明: 求kn中与n互质的个数,答案为k?(n). ?(n)表示1-n中与n互质的个数,那么由此考虑[n + 1, 2n], [2n + 1, 3n]...这每个区间