题目:Mark the Rope

题意就是给一个数,然后求这个数的所有因子中组成的最大的一个子集,其中1和本身除外,使得在这个子集中元素两两互素,求最大子集的元素个

数,并且求出和最大的值。

找规律就不难发现其实答案就是先大数分解n,例如,180=2^2*3^2*5,那么就输出3   18   ,这两个数分别是素因子的个数和2^2,3^2,5的和。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <iostream> const int Times=10;
const int N=550; using namespace std;
typedef unsigned __int64 LL; LL ct,cnt;
LL fac[N],num[N]; LL gcd(LL a,LL b)
{
return b? gcd(b,a%b):a;
} LL multi(LL a,LL b,LL m)
{
LL ans=0;
while(b)
{
if(b&1)
{
ans=(ans+a)%m;
b--;
}
b>>=1;
a=(a+a)%m;
}
return ans;
} LL quick_mod(LL a,LL b,LL m)
{
LL ans=1;
a%=m;
while(b)
{
if(b&1)
{
ans=multi(ans,a,m);
b--;
}
b>>=1;
a=multi(a,a,m);
}
return ans;
} bool Miller_Rabin(LL n)
{
if(n==2) return true;
if(n<2||!(n&1)) return false;
LL a,m=n-1,x,y;
int k=0;
while((m&1)==0)
{
k++;
m>>=1;
}
for(int i=0;i<Times;i++)
{
a=rand()%(n-1)+1;
x=quick_mod(a,m,n);
for(int j=0;j<k;j++)
{
y=multi(x,x,n);
if(y==1&&x!=1&&x!=n-1) return false;
x=y;
}
if(y!=1) return false;
}
return true;
} LL Pollard_rho(LL n,LL c)
{
LL x,y,d,i=1,k=2;
y=x=rand()%(n-1)+1;
while(true)
{
i++;
x=(multi(x,x,n)+c)%n;
d=gcd((y-x+n)%n,n);
if(1<d&&d<n) return d;
if(y==x) return n;
if(i==k)
{
y=x;
k<<=1;
}
}
} void find(LL n,int c)
{
if(n==1) return;
if(Miller_Rabin(n))
{
fac[ct++]=n;
return ;
}
LL p=n;
LL k=c;
while(p>=n) p=Pollard_rho(p,c--);
find(p,k);
find(n/p,k);
} int main()
{
int t;
LL n,ans;
scanf("%d",&t);
while(t--)
{
scanf("%I64u",&n);
ct=0;
find(n,120);
sort(fac,fac+ct);
num[0]=1;
int k=1;
for(int i=1;i<ct;i++)
{
if(fac[i]==fac[i-1])
++num[k-1];
else
{
num[k]=1;
fac[k++]=fac[i];
}
}
cnt=k;
LL ret=0;
for(int i=0;i<cnt;i++)
{
LL temp=1;
for(int j=0;j<num[i];j++)
temp*=fac[i];
ret+=temp;
}
if(cnt==1) ret/=fac[0];
printf("%I64u %I64u\n",cnt,ret);
}
return 0;
}
04-14 06:37