http://acm.hdu.edu.cn/showproblem.php?pid=3388
从1到1e18二分查找,然后进行容斥原理计算
容斥原理在运用的时候要结合题意,有可能不是计算lcm
注意容斥原理的灵活运用
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <set>
#define ll long long
using namespace std;
const int maxn=25;
int a[200];
int num=0;ll all=0;int t;int m,n,k;
const ll INF=(ll)1<<62;
void fen(int k)
{
for(int i=2;i*i<=k;i++)
{
if(k%i==0)
{
a[num++]=i;
while(k%i==0)
k=k/i;
}
}
if(k>1)
a[num++]=k;
}
ll ge(ll s)
{
all=0;
for(int i=1;i<(1<<num);i++)
{
ll lcm=1;int k=0;
for(int j=0;j<num;j++)
{
if(i&(1<<j))
{
k++;
lcm=(lcm*a[j]);//**注意这里不用求最小公倍数因为都是质数**
}
}
if(k&1)
all+=s/lcm;
else
all-=s/lcm;
}
return s-all;
}
ll binary()
{
ll l=1,r=INF;
while(l<=r)
{
ll mid=(l+r)/2;
if(ge(mid)>=k)
{
r=mid-1;
}
if(ge(mid)<k)
l=mid+1;
}
return l;
}
int main()
{
int sss=1;
scanf("%d",&t);
while(t--)
{
num=0;
scanf("%d%d%d",&m,&n,&k);
fen(m);
fen(n);
sort(a,a+num);
num=unique(a,a+num)-a;//**去重函数 复杂度不是O(n)返回值是指针**
ll jieguo=binary();
printf("Case %d: %I64d\n",sss++,jieguo);
}
return 0;
}
还可以用下面的方法O(n)去重:
sort(a,a+num);
b[0]=a[0];shu=1;
for(int i=1;i<num;i++)
{
if(a[i]!=a[i-1])
b[shu++]=a[i];
}