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;
}
浙公网安备 33010602011771号