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; }