codevs 4248

来源:互联网 发布:curl php 可跳转 编辑:程序博客网 时间:2024/05/16 12:41

我终于做出来了!!!!!(虽然看了题解。。。)

Ps:大神的题解太牛了,我看了一个多小时才看懂。。。

昨天那道题吧,认真想了一会,我就找着了门道,其实就是sum(φ(m)),m为n的约数(1除外)且能被一个完全平方数整除。接着就是枚举,然后求欧拉函数。提交!

我本以为能骗那么个三四十分的,谁知——0分!!!!!所有的点超时!!!

我的天啊,太不人道了!10分都不给我。。。

接着我就试着打个欧拉函数表,优化一下因数分解的方法。然而,并没有什么卵用。。。

于是,我屈服了,打开了大神的题解和代码。

我本以为看了一眼后一切问题就会迎刃而解,可是理想很丰满,现实很骨感。。。

“天啊!”

“这写的都是啥!!!”

“这是什么鬼东西!!!!”

其实我的基本思路是对的,这道题无非就是求上述的那些东西。但是我们的解题方法却相差很远。打个比方吧,我走路,人家坐飞机。我在前面已经将我的步子一一说明了。而至于人家坐的是什么“飞机”呢,接下来就是见证奇迹的时刻:

1.  不直接枚举能被某个完全平方数整除的n的约数,而是枚举既是n的因子又不是任何一个大于1的完全平方数的倍数的数,而本题的答案就是n减去既是n的因子又不是任何一个大于1的完全平方数的倍数的数的欧拉函数的总和。

2. 接下来就是分解质因数,而我也恰恰是在这里卡了好久,因为题解了忽然冒出了一个Pollard rho算法,让我立马就蒙了。然后,我就在网上翻了一个小时的资料,找这个算法。。。至于这个算法是什么,我在此就不做赘述了。以下是对我有较大帮助的几篇文章:

https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm

http://www.cnblogs.com/jackiesteed/articles/2019910.html

http://blog.sina.com.cn/s/blog_86a9d97201015cj7.html

接下来请大家继续欣赏“飞机”。。。

3.     在找质因数的过程中,我们或许会用到质数判断的算法,在我的程序中,我用的是枚举法(我也是醉了。。。)。但是,人家的代码让我想起了一个奇怪的算法。这个算法我曾经用过一次,它miller rabin算法。不过我现在差不多忘光光了,所以我也借此温习了一番。至于这个算法是什么,我在此就不做赘述了。。。

以下是对我有较大帮助的一篇文章:

http://blog.chinaunix.net/uid-26856484-id-3182166.html

 

 

最后附上本题AC代码(官方标程)

 

#include<cstdio>#include<algorithm>#define C 2730#define S 3using namespace std;typedef long long ll;int T,t,i;ll n,m,q[100];ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}inline ll mul(ll a,ll b,lln){return(a*b-(ll)(a/(long double)n*b+1e-3)*n+n)%n;}inline ll pow(ll a, ll b, ll n){  lld=1; a%=n; while(b){   if(b&1)d=mul(d,a,n);   a=mul(a,a,n);   b>>=1;  } return d;}inline bool check(ll a,ll n){  llm=n-1,x,y;int i,j=0; while(!(m&1))m>>=1,j++; x=pow(a,m,n); for(i=1;i<=j;x=y,i++){   y=pow(x,2,n);   if((y==1)&&(x!=1)&&(x!=n-1))return 1;  } return y!=1;}inline bool miller_rabin(int times,ll n){ if(n==1)return 0; if(n==2)return 1; if(!(n&1))return 0; while(times--)if(check(rand()%(n-1)+1,n))return 0; return 1;}inline ll pollard_rho(ll n,int c){  lli=1,k=2,x=rand()%n,y=x,d; while(1){   i++,x=(mul(x,x,n)+c)%n,d=gcd(y-x,n);   if(d>1&&d<n)return d;   if(y==x)return n;   if(i==k)y=x,k<<=1;  }}void findfac(ll n,int c){ if(n==1)return; if(miller_rabin(S,n)){   q[++t]=n;   return;  }  llm=n; while(m==n)m=pollard_rho(n,c--); findfac(m,c),findfac(n/m,c);}int main(){ scanf("%d",&T); while(T--){   scanf("%lld",&n);   t=0;   findfac(n,C);   sort(q+1,q+t+1);   for(i=m=1;i<=t;i++)if(q[i]!=q[i-1])m*=q[i];   printf("%lld\n",n-m);  } return 0;}   llm=n; while(m==n)m=pollard_rho(n,c--); findfac(m,c),findfac(n/m,c);}int main(){ scanf("%d",&T); while(T--){   scanf("%lld",&n);   t=0;   findfac(n,C);   sort(q+1,q+t+1);   for(i=m=1;i<=t;i++)if(q[i]!=q[i-1])m*=q[i];   printf("%lld\n",n-m);  } return 0;}


 

0 0
原创粉丝点击