51nod oj 1040 最大公约数之和 1060 最复杂的数【打表+筛重】

题目来源:  rihkddd
基准时间限制:1 秒 空间限制:131072 KB 分值: 80  难度:5级算法题
 收藏
 关注
给出一个n,求1-n这n个数,同n的最大公约数的和。比如:n = 6
1,2,3,4,5,6 同6的最大公约数分别为1,2,3,2,1,6,加在一起 = 15
Input
1个数N(N <= 10^9)
Output
公约数之和
Input示例
6
Output示例
15


思路:先打约数表---再排序,然后从大到小算每个公约数的个数(要筛重)---

ps: 10^9中最多约数的数是931170240   有 1344个



PS:引用-.-

废铁圣斗士(44785644) 21:02:45
一个数约数的个数就是质因子的幂加一然后相乘,所以2的幂是一个或多个,其余从3开始的幂都是1吧?

绿色夹克衫(1178939527) 21:12:18
例如n = p1^m1 * p2^m2 * p3^m3...... 那么约数数量 = (m1 + 1)*(m2 + 1) *(m3 + 1)......

绿色夹克衫(1178939527) 21:14:00
180 = 2^2 * 3^2 * 5,所以180的约数数量是3 * 3 * 2

绿色夹克衫(1178939527) 21:15:06
既然要求最小的,那么你让p1 = 2, p2 = 3, p3 = 5......


代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
int p[40000],a[40000];
int main()
{
	int n;scanf("%d",&n);
	int kai=sqrt(n),kp=0;
	memset(a,0,sizeof(a));
	for (int i=1;i<=kai;i++)
	{
		if (n%i==0)
		{
			p[kp++]=i;
			p[kp++]=n/i;
		}
	}
	if (n==kai*kai) kp--;
//	printf("%d\n",kp);
	sort(p,p+kp);long long ans=0;
	for (int i=kp-1;i>=0;i--)
	{
		a[i]=n/p[i];
		for (int j=i+1;j<kp;j++)
			if (p[j]%p[i]==0)
				a[i]-=a[j];
		ans+=a[i]*p[i];
	//	printf("%d   %d   %d\n",p[i],a[i],ans);
	}
	printf("%lld\n",ans);
	return 0;
}

ps:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define P 1000000000
#define LL long long
LL k=0,ji=0;
int p[15]={2,3,5,7,11,13,17,19,23,29,31,37,41};
void dfs(int xx,LL shu,LL ge)
{
	if (shu*p[xx]>P)
	{
		if (ge>ji)
		{
			ji=ge;
			k=shu;
		}
		return ;
	}
	for (int i=1;shu*p[xx]<=P;i++)
		dfs(xx+1,shu*=p[xx],ge*(i+1));
}
int main()
{
	dfs(0,1,1);
	printf("%d   %d\n",k,ji);
	return 0;
}



题目来源:  Ural 1748
基准时间限制:1 秒 空间限制:131072 KB 分值: 40  难度:4级算法题
 收藏
 关注
把一个数的约数个数定义为该数的复杂程度,给出一个n,求1-n中复杂程度最高的那个数。
例如:12的约数为:1 2 3 4 6 12,共6个数,所以12的复杂程度是6。如果有多个数复杂度相等,输出最小的。
Input
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 100)
第2 - T + 1行:T个数,表示需要计算的n。(1 <= n <= 10^18)
Output
共T行,每行2个数用空格分开,第1个数是答案,第2个数是约数的数量。
Input示例
5
1
10
100
1000
10000
Output示例
1 1
6 4
60 12
840 32
7560 64


这才算打表呀-.-文件打表!!


代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
LL k,ji,P=1000000000000000000;
int p[20]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61};
void dfs(int xx,LL shu,LL ge)
{
	if (P/p[xx]<shu)
	//if (sqrt(shu)*sqrt(p[xx])>sqrt(P))
	{
		if (ge>ji)
		{
			ji=ge;
			k=shu;
		}
		else if (ge==ji&&shu<k)
			k=shu;
		return ;
	}
	for (int i=1;sqrt(shu)*sqrt(p[xx])<=sqrt(P);i++)
		dfs(xx+1,shu*=p[xx],ge*(i+1));
}
struct node{
	LL hao ,ge;
}dian[156]={
{897612484786617600,103680},
{748010403988848000,98304},
{673209363589963200,96768},
{448806242393308800,92160},
{374005201994424000,86016},
{299204161595539200,82944},
{224403121196654400,80640},
{149602080797769600,73728},
{112201560598327200,69120},
{106858629141264000,65536},
{74801040398884800,64512},
{72779390658374400,62208},
{60649492215312000,61440},
{48519593772249600,57600},
{36389695329187200,55296},
{30324746107656000,53760},
{24259796886124800,51840},
{20216497405104000,49152},
{18194847664593600,48384},
{12129898443062400,46080},
{10108248702552000,43008},
{8086598962041600,41472},
{6064949221531200,40320},
{4043299481020800,36864},
{3032474610765600,34560},
{2888071057872000,32768},
{2021649740510400,32256},
{1732842634723200,30720},
{1516237305382800,28800},
{1444035528936000,28672},
{1010824870255200,27648},
{866421317361600,26880},
{782574093100800,25920},
{577614211574400,24576},
{391287046550400,23040},
{288807105787200,21504},
{260858031033600,20736},
{195643523275200,20160},
{130429015516800,18432},
{97821761637600,17280},
{93163582512000,16384},
{65214507758400,16128},
{55898149507200,15360},
{48910880818800,14400},
{46581791256000,14336},
{32607253879200,13824},
{27949074753600,13440},
{26985313555200,12960},
{18632716502400,12288},
{13492656777600,11520},
{9316358251200,10752},
{8995104518400,10368},
{6746328388800,10080},
{4497552259200,9216},
{3373164194400,8640},
{3212537328000,8192},
{2248776129600,8064},
{1927522396800,7680},
{1686582097200,7200},
{1606268664000,7168},
{1124388064800,6912},
{963761198400,6720},
{642507465600,6144},
{481880599200,5760},
{321253732800,5376},
{293318625600,5040},
{240940299600,4800},
{160626866400,4608},
{146659312800,4320},
{128501493120,4096},
{97772875200,4032},
{80313433200,3840},
{73329656400,3600},
{64250746560,3584},
{48886437600,3456},
{41902660800,3360},
{27935107200,3072},
{20951330400,2880},
{13967553600,2688},
{10475665200,2400},
{6983776800,2304},
{5587021440,2048},
{4655851200,2016},
{3491888400,1920},
{2793510720,1792},
{2327925600,1728},
{2205403200,1680},
{2095133040,1600},
{1396755360,1536},
{1102701600,1440},
{735134400,1344},
{698377680,1280},
{551350800,1200},
{367567200,1152},
{294053760,1024},
{245044800,1008},
{183783600,960},
{147026880,896},
{122522400,864},
{110270160,800},
{73513440,768},
{61261200,720},
{43243200,672},
{36756720,640},
{32432400,600},
{21621600,576},
{17297280,512},
{14414400,504},
{10810800,480},
{8648640,448},
{7207200,432},
{6486480,400},
{4324320,384},
{3603600,360},
{2882880,336},
{2162160,320},
{1441440,288},
{1081080,256},
{720720,240},
{665280,224},
{554400,216},
{498960,200},
{332640,192},
{277200,180},
{221760,168},
{166320,160},
{110880,144},
{83160,128},
{55440,120},
{50400,108},
{45360,100},
{27720,96},
{25200,90},
{20160,84},
{15120,80},
{10080,72},
{7560,64},
{5040,60},
{2520,48},
{1680,40},
{1260,36},
{840,32},
{720,30},
{360,24},
{240,20},
{180,18},
{120,16},
{60,12},
{48,10},
{36,9},
{24,8},
{12,6},
{6,4},
{4,3},
{2,2},
{1,1}
};
int main()
{
	//int t;scanf("%d",&t); 
	/*while (t--)
	{
		scanf("%lld",&P);9
		k=0;ji=0;
		dfs(0,1,1);
		printf("%lld %lld\n",k,ji);
	}*/
	//freopen("out.txt","w",stdout);
	int kp=156;
	k=0;ji=0;
	/*while (P!=1)
	{
		dfs(0,1,1);
		P=k-1;
		dian[kp].hao=k;
		dian[kp++].ge=ji;
		printf("{%lld,%lld},\n",k,ji); 
		k=0;ji=0;
	}
	dian[kp].hao=1;
	dian[kp++].ge=1;
	printf("{%lld,%lld},\n",dian[kp-1].hao,dian[kp-1].ge); 
	printf("%d\n",kp);*/
	int t;scanf("%d",&t);
	while (t--)
	{
		scanf("%lld",&P);
		for (int i=kp-1;i>=0;i--)
		{
			if (P>=dian[i].hao)
			{
				k=dian[i].hao;
				ji=dian[i].ge;
			}
			else
				break;
		}
		printf("%lld %lld\n",k,ji);
	}
	return 0;
}











评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值