原题:qwb与支教
原题大意
qwb同时也是是之江学院的志愿者,暑期要前往周边地区支教,为了提高小学生的数学水平。她把小学生排成一排,从左至右从1开始依次往上报数。
玩完一轮后,他发现这个游戏太简单了。于是他选了3个不同的数x,y,z;从1依次往上开始报数,遇到x的倍数、y的倍数或z的倍数就跳过。如果x=2,y=3,z=5;第一名小学生报1,第2名得跳过2、3、4、5、6,报7;第3名得跳过8、9、10,报11。
那么问题来了,请你来计算,第N名学生报的数字是多少?
算法分析
二分+容斥原理,详见代码
程序代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9+7;
ll x, y, z, n;
ll gcd(ll a, ll b){
return b == 0?a:gcd(b, a%b);
}
ll lcm(ll a, ll b){
return a*b/gcd(a,b);
}
ll check(ll w){
return w/x+w/y+w/z-w/lcm(x,y)-w/lcm(x,z)-w/lcm(z,y)+w/lcm(lcm(x,y),z);
}
ll ans;
int main(){
while(scanf("%lld%lld%lld%lld",&x, &y, &z, &n) != EOF){
ll l = 1, r = 1e18;
while(l<=r){
ll m = (l+r)>>1;
if(m - check(m) < n) l = m+1;
else{
ans = m;
r = m-1;
}
}
printf("%lld\n", ans);
}
return 0;
}