链接
题面
题意
求第 k k k个只能被 N N N或 M M M整除的数
题解
[
1
,
x
]
[1,x]
[1,x]中的能被
n
n
n整除的数有
⌊
x
n
⌋
\lfloor \frac{x}{n} \rfloor
⌊nx⌋个
[
1
,
x
]
[1,x]
[1,x]中的能被
m
m
m整除的数有
⌊
x
m
⌋
\lfloor \frac{x}{m} \rfloor
⌊mx⌋个
[
1
,
x
]
[1,x]
[1,x]中的能被
n
n
n或
m
m
m整除的数有
⌊
x
n
∗
m
⌋
\lfloor \frac{x}{n*m} \rfloor
⌊n∗mx⌋个
[
1
,
x
]
[1,x]
[1,x]中的只能被
n
n
n或
m
m
m中一个数整除的数有
⌊
x
n
⌋
+
⌊
x
m
⌋
−
2
∗
⌊
x
n
∗
m
⌋
\lfloor \frac{x}{n} \rfloor + \lfloor \frac{x}{m} \rfloor-2*\lfloor \frac{x}{n*m} \rfloor
⌊nx⌋+⌊mx⌋−2∗⌊n∗mx⌋个
然后可以观察到答案具有单调性,能被 n 、 m n 、 m n、m整除的数的个数随答案的增大增大。
代码
#include <bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(int i = (a); i <= (b); ++i)
#define fep(i,a,b) for(int i = (a); i >= (b); --i)
#define pii pair<int, int>
#define pdd pair<double,double>
#define ll long long
#define db double
#define endl '\n'
#define x first
#define y second
#define pb push_back
#define vi vector<int>
using namespace std;
const int maxn=1e5+10;
void solve() {
int n,m,k;
cin>>n>>m>>k;
int lcm=n*m/__gcd(n,m);
int l=0,r=2e18;
auto check=[&](int tar){
if(tar/n+tar/m-2*(tar/lcm)>=k) return true;
return false;
};
while(l<r){
int mid=(l+r)>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
cout<<l<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
// freopen("1.in", "r", stdin);
int _;
// cin>>_;
// while(_--)
solve();
return 0;
}
总结
[
1
,
x
]
[1,x]
[1,x]中的能被
n
n
n整除的数有
⌊
x
n
⌋
\lfloor \frac{x}{n} \rfloor
⌊nx⌋个
[
1
,
y
]
[1,y]
[1,y]中的能被
n
n
n整除的数有
⌊
y
n
⌋
\lfloor \frac{y}{n} \rfloor
⌊ny⌋个
[
x
,
y
]
[x,y]
[x,y]中的能被
n
n
n整除的数有
⌊
y
n
⌋
−
⌊
x
n
⌋
\lfloor \frac{y}{n} \rfloor - \lfloor \frac{x}{n} \rfloor
⌊ny⌋−⌊nx⌋个