HDOJ-4344 Mark the Rope(数论)
来源:互联网 发布:淘宝米折报名入口 编辑:程序博客网 时间:2024/06/14 06:34
概括一下题意:将一个合数n的因数(不包括1和n)看做一个集合,求一个最大的子集使集合内所有元素都互质,并求出在上述条件下集合元素最大的和是多少。
解法:既然要保证子集内的元素互质,就要保证任意两个元素没有质因子。要元素数目做多,则每个元素包含的质因子数目最少,即为1。
做法也就出来了,对n进行拆分质因数,表示成 n=(a1^p1)*(a2^p2)*(a3^p3)*......*(ak^pk),则子集大小就是k,子集所有元素的最大的和就是(a1^p1)+(a2^p2)+(a3^p3)+......+(ak^pk)。当然,有一种特殊情况,就是n只有一种质因数,n=a^p,例如16,9等等,因为n不在大的集合之内,所以sum=a^(p-1)
现在转化为了大数快速分解质因数的问题,可以使用神奇的“pollard-rho”算法
传送门:http://www.cnblogs.com/jackiesteed/articles/2019910.html
在pollard-rho算法中用到了Miller-Rabin素数检验
传送门:http://www.matrix67.com/blog/archives/234
如果感觉自己很难理解,还是老老实实套模板吧:
(kuangbin模板)
#include <ctime>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;/*Miller_Rabin 算法判断是否为素数*/const int S=8;//ret=(a*b)%c;LL mult_mod(LL a,LL b,LL c){a %= c;b %= c;LL ret=0;LL tmp=a;while(b){if(b&1){ret+=tmp;if(ret>c) ret-=c;}tmp<<=1;if(tmp>c) tmp-=c;b>>=1;}return ret;}//res=x^n %mod;LL pow_mod(LL x,LL n,LL mod){ LL t,res; res=1;t=x; while(n) { if(n&1)res=mult_mod(res,t,mod); n>>=1; t=mult_mod(t,t,mod); } return res;}//是合数返回1,不一定是合数返回0bool check(LL a, LL n, LL x, LL t){int i;LL ret=pow_mod(a,x,n);LL last=ret;for(i=1;i<=t;i++){ret=mult_mod(ret,ret,n);if(ret==1 && last!=1 && last!=n-1) return 1;last=ret;}if(ret!=1)return 1;elsereturn 0;}//很可能是素数返回1,一定不是素数返回0bool Miller_Rabin(LL n){int i;if (n<2) return 0;if (n==2) return 1;if ((n&1)==0) return 0;LL x=n-1;LL t=0;while((x&1)==0){x>>=1;t++;}srand(time(NULL));for(i=0;i<S;i++){LL a=rand()%(n-1)+1;if(check(a,n,x,t))return 0;}return 1;}/*pollard_rho算法进行质因数分解*/LL factor[1000];int tol;//质因数个数LL gcd(LL a,LL b){LL t;while(b){t=a;a=b;b=t%b;}if(a>=0) return a;else return -a;}LL pollard_rho(LL x,LL c){LL i=1,k=2;srand(time(NULL));LL x0=rand()%(x-1)+1;LL y=x0;while(1){i++;x0=(mult_mod(x0,x0,x)+c)%x;LL d=gcd(y-x0,x);if(d!=1 && d!=x) return d;if(y==x0) return x;if(i==k){y=x0;k+=k;}}}void findfac(LL n,int k){if(n==1) return ;if(Miller_Rabin(n)){factor[tol++]=n;return ;}LL p=n;int c=k;while(p>=n)p=pollard_rho(p,c--);findfac(p,k);findfac(n/p,k);}void work(){int i;LL n,ans,tmp,cnt;scanf("%I64d",&n);tol=0;findfac(n,107);sort(factor,factor+tol);ans=0;tmp=factor[0];cnt=1;for(i=1;i<tol;i++){if(factor[i]!=factor[i-1]){cnt++;ans+=tmp;tmp=factor[i];}else{tmp*=factor[i];}}ans+=tmp;if(cnt==1) ans/=factor[0];printf("%I64d %I64d\n",cnt,ans);}int main(){int T;scanf("%d",&T);while(T--)work();return 0;}
0 0
- HDOJ-4344 Mark the Rope(数论)
- hdu 4344 Mark the Rope
- hdu 4344 Mark the Rope
- HDU 4344 Mark the Rope
- hdu - 4344 - Mark the Rope - 大数分解
- hdu-4344-Mark the Rope-大数分解质因子模板
- hdu 4344 Mark the Rope (Miller Rabbin + Pollard rho)
- HDU 4344 Mark the Rope Pollard_Rho大数分解
- 大数分解质因数:Mark the Rope
- hdu 4344 Mark the Rope (质因子分解+米勒拉宾素性)
- hdu4344 Mark the Rope-------多校联合五
- 2012 Multi-University Training Contest 5:Mark the Rope
- HDU4344 Mark the Rope pollard_rho大整数分解应用
- 2012 Multi-University Training Contest 5-1006 hdu4344 Mark the Rope
- HDOJ 5373 The shortest problem 【数论】
- cocos2d cut the rope
- hdu_4476_Cut the rope
- The Rope Bridge
- DZY Loves Chemistry
- 设置导航栏的背景色
- Java--equals 和 ==
- 大学生应对面试宝典(电话、现场面试)
- Android网络连接之HttpURLConnection和HttpClient
- HDOJ-4344 Mark the Rope(数论)
- HDU 1874 畅通工程续
- C++ 和 lua代码互相调用
- git基本命令
- Word Ladder
- floyd算法(循环问题)
- 巧用array_map()和array_reduce()替代foreach循环
- JSF 入门教程
- springmvc的数据回显