2011 多校联合第5场 1002 Lucky Numbers

http://acm.hdu.edu.cn/showproblem.php?pid=3880

比赛的时候卡了很久,最后yy出一个很奇怪的结论,现在给出一点简单的证明。

题意大概是给出互质的两个数a,b. 还有一个边界数M。

求出一个 具有最小元素的 setA 集合,使得对任意正整数m ( a*m<=M && b*m<=M) . a*m or b*m is in setA.

首先假设 a<b.  ( gcd(a,b)=1)

设整个范围是 (b*1,b*2,b*3, .........b*t)  (b*t<=M) 个数是 M/b;

设 ans = 0;

(1) ans 加上 M以内能被b整除的数的个数       

 ans += M/b ; ( M/b , 这个是要最基本满足的个数)

(2) ans 减去 M以内能被b^2 整除的数的个数 

    第一种情况:

    t1 = b^2*p ;  (b不能整除p)

    t2 = a*b*p ;  也就是说 b^2*p 这个数是多余的(可以删除),因为这个数早已经被包含在只能被一个b整除的数当中( a*b*p) .

    第二种情况:

    t1 = b^2*p = b^3*p1 ; (b能整除p)

    t2 = a*b^2*p; (因为已经减去能被b^2整除的数,所以t2不存在)

    所以接下来要加回能被b^3整除的t1这种类型的数,

(3) ans  加上 M以内能被b^3 整除的数的个数

   同理:

(4) ans 减去 M以内能被b^4 整除的数的个数

(5)..........................

    ...........................

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string.h>
using namespace std;

int main()
{

	int a,b,M;
	while(scanf("%d %d %d",&a,&b,&M)!=EOF)
	{
		if(a==1 && b==1)
		{
			printf("%d\n",M);
			continue;
		}
		if(a>b)
			swap(a,b);
		int sum = 0;
		int t =1;
		while(M>=b)
		{
			sum += t*(M/b);
			M/=b;
			if(t==1)
				t = -1;
			else
				t = 1;
		}
		printf("%d\n",sum);
	}
	return 0;
}

posted on 2011-07-28 00:59  lwbaptx  阅读(370)  评论(1编辑  收藏  举报

导航