【数论】MMT数解题报告

来源:互联网 发布:九月份非农数据 编辑:程序博客网 时间:2024/05/17 23:27

2、MMT数

FF博士最近在研究MMT数(莫明堂数-_-)。

如果对于一个数n,存在gcd(n,x)<>1并且n mod x<>0 那么x叫做n的MMT数

显然这样的数可以有无限个。

FF博士现在想知道在所有小于n的正整数里面有多少个n的MMT数

输入样例:

10

 

输出样例:

3

 

样例解释: 3个数分别是 4 6 8

gcd(n,x)的意思是求n和x的最大公约数

 

对于50%的数据 n<=1000000

对于100%的数据n<=maxlongint

 

 

【考察点】

数论,准确地说,欧拉函数

【思路】

反正我考试的时候是没有办法的……朴素了50分。

看完解题报告后,我还是推不出那个破公式,于是只能直接用结论了……

(以下复制)

这道题定位为纯数论题..因为实在不知道该怎么藏算法。

假设一个数n分解质因数以后为p1^k1*p2^k2*p3^k3……(p为质因数)

那么他的因数个数为a=(k1+1)*(k2+1)*(k3+1)…

在所有比n小的数里与n互质的数的个数其实就是欧拉函数,b=n*[1-(1/p1)]*[1-(1/p2)]*[1-(1/p3)]

这两种数里都含有1,所以n的MMT数为n-(a+b-1)。

纯模拟也可以有50分。

至于怎么分解质因数就不用说了吧,算素数或者打素数表都可以。

>_<不会欧拉函数的童鞋就当学了个新知识吧,也许以后会有用哦。

【提交情况】

考试TLE50,下来搞了很久之后AC

【经验及收货】

素数这种东西果然还是打表让人舒服些……

【吐槽】

该死的数论……给各种数学牛跪了……给能手动推出欧拉函数的跪了……

 

ACCode:

 

Program mmt;Var a,b,c:array[0..10000]of longint;f:array[0..10000]of boolean;n:longint;Procedure terminate;beginclose(input);close(output);halt;end;Procedure init;beginassign(input,'mmt.in');assign(output,'mmt.out');reset(input);rewrite(output);readln(n);end;Procedure main;vari,j,k,m,x,y,t,tot,z,h,tt:longint;s:real;flag:boolean;beginm:=n;h:=0;t:=0;for j:=2 to trunc(sqrt(maxlongint)) dobeginflag:=true;for i:=2 to trunc(sqrt(j)) doif j mod i=0 then begin flag:=false;break;end;if flag then begin inc(t);a[t]:=j;end;end;for i:=1 to t dowhile n mod a[i]=0 dobegin inc(c[i]);n:=n div a[i];end;if n<>1 then begin a[t+1]:=n;c[t+1]:=1;inc(t);end;tt:=1; n:=m;for i:=1 to t do tt:=tt*(c[i]+1);s:=m;for i:=1 to t dobeginif c[i]=0 then continue;s:=s-s/a[i];end;s:=round(s);writeln(n-(tt+s-1):0:0);end;Begininit;main;terminate;End.