题意
给出一个n,求一个数x,x在1到n之间,并且x/φ(x)最大(其中φ(x)为x的欧拉函数)。
思路
前两天刚学了欧拉函数,不过这题拿过来还是不知道要做什么。后来还是忍着没看题解,然后上百度百科看欧拉函数,然后什么都知道了。。。还是之前学的不好啊,只是知道了一些皮毛根本没搞清楚到底是怎样的。做完这题算是对这个函数的理解更深刻了吧。
首先来看欧拉函数的通式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn)。
于是x/φ(x)=1/(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)…..(1-1/pn)。
这样的话答案就一目了然了,让想让原式更大就需要让分母更小。因为下面的项都是小于1的,所以项越多原式就越大。而1/pn是小于1的,所以需要让1/pn更大也就是让pn更小。
又因为每种质因数只一个。比如12=223那么φ(12)=12(1-1/2)(1-1/3)=4。
所以答案显而易见就是尽量小的质数的相乘,也就是
2=2 (1-5)
6=23 (6-29)
30=235 (30-119)
120=2357 (120-2309)
2310=235711 …
… …
就是这样打一个质数相乘的表然后输入n直接查询即可。
因为数据很大于是用java写的大数,然后就开始TLE了。。。
改了很多种写法。。TLE了8次然后我去看了一下discuss。。。这题竟然卡java。
所以之前java可以过的现在也过不去了,我去网上找了一篇题解交了一下果然TLE了。
于是我就改成了C++。。。但是C++的高精度写起来实在太麻烦了。。。我就用java打表输出,然后在C++里面用字符串储存过了这题。
真坑。。。
附上C++打表AC的代码和JAVA答案正确但是TLE的代码。
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
const int INF = 0x3f3f3f3f; const double eps = 1e-4; char a[][100] = { "2", "6", "30", "210", "2310", "30030", "510510", "9699690", "223092870", "6469693230", "200560490130", "7420738134810", "304250263527210", "13082761331670030", "614889782588491410", "32589158477190044730", "1922760350154212639070", "117288381359406970983270", "7858321551080267055879090", "557940830126698960967415390", "40729680599249024150621323470", "3217644767340672907899084554130", "267064515689275851355624017992790", "23768741896345550770650537601358310", "2305567963945518424753102147331756070", "232862364358497360900063316880507363070", "23984823528925228172706521638692258396210", "2566376117594999414479597815340071648394470", "279734996817854936178276161872067809674997230", "31610054640417607788145206291543662493274686990", "4014476939333036189094441199026045136645885247730", "525896479052627740771371797072411912900610967452630", "72047817630210000485677936198920432067383702541010310", "10014646650599190067509233131649940057366334653200433090", "1492182350939279320058875736615841068547583863326864530410", "225319534991831177328890236228992001350685163362356544091910", "35375166993717494840635767087951744212057570647889977422429870", "5766152219975951659023630035336134306565384015606066319856068810", "962947420735983927056946215901134429196419130606213075415963491270", "166589903787325219380851695350896256250980509594874862046961683989710", "29819592777931214269172453467810429868925511217482600306406141434158090", "5397346292805549782720214077673687806275517530364350655459511599582614290", "1030893141925860008499560888835674370998623848299590975192766715520279329390", "198962376391690981640415251545285153602734402721821058212203976095413910572270", "39195588149163123383161804554421175259738677336198748467804183290796540382737190", "7799922041683461553249199106329813876687996789903550945093032474868511536164700810", "1645783550795210387735581011435590727981167322669649249414629852197255934130751870910", "367009731827331916465034565550136732339800312955331782619462457039988073311157667212930", "83311209124804345037562846379881038241134671040860314654617977748077292641632790457335110", "19078266889580195013601891820992757757219839668357012055907516904309700014933909014729740190", "4445236185272185438169240794291312557432222642727183809026451438704160103479600800432029464270", "1062411448280052319722448549835623701226301211611796930357321893850294264731624591303255041960530", "256041159035492609053110100510385311995538591998443060216114576417920917800321526504084465112487730", "64266330917908644872330635228106713310880186591609208114244758680898150367880703152525200743234420230" }; char str[100]; int main() { //freopen("H:\\in.txt","r",stdin); //freopen("H:\\out.txt","w",stdout); int T; scanf("%d",&T); while(T--) { scanf("%s",str); int x = strlen(str); int i; for( i = 0; i < 60; i++) { int y = strlen(a[i]); if (x < y) break; if (x > y) continue; if (strcmp(str,a[i]) < 0) break; } printf("%s\n",a[i-1]); } return 0; } |
JAVA代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import java.io.*; import java.math.*; import java.util.Scanner; public class Main { static int k; static int[] temp = new int[300]; static BigInteger[] prime = new BigInteger[60]; static void table() { for(int i = 0; i < 300; i++) { temp[i] = 1; } k = 0; temp[1] = 0; for(int i = 2; i < 242; i++) if (temp[i] != 0) { prime[k] = BigInteger.valueOf(i); k++; for(int j = 2*i; j < 242; j+=i) temp[j] = 0; } for(int i = 1; i < k; i++) { prime[i] = prime[i].multiply(prime[i-1]); } } public static void main (String[] args) { Scanner cin = new Scanner (system.in); int T; T = cin.nextInt(); table(); while(T > 0) { T--; BigInteger n = cin.nextBigInteger(); int i; for(i = 0; i < k; i++) { if (n.compareto(prime[i]) < 0) break; } System.out.println(prime[i-1]); } } } |