hdu 3388 Coprime

第一个容斥的题,感觉这东西好神啊。于是扒了一发题解2333

首先想对于[1,x]内有多少与n,m都互质的数,显然x是存在单调性的,所以可以二分一下。

那么互质的数的求法,就是x-存在n,m一个质因数的+存在2个质因数-3+4.....暴力搜索就可以(搜索都不会写233)

#include<bits/stdc++.h>
#define N 100005
#define M 10000005
#define lowbit(x) x&(-x)
#define LL long long
#define inf 0x3f3f3f3f
using namespace std;
inline int ra()
{
    int x=0,f=1; char ch=getchar();
    while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
map<int ,bool > mp;
int n,m,k,cnt;
LL p[N];
void getprime(LL x)
{
    for (LL i=2; i*i<=x; i++)
    {
        if (x%i==0 && !mp[i])
        {
            mp[i]=1; p[++cnt]=i;
        }
        while (x%i==0) x/=i;
    }
    if (x>1 && !mp[x]) mp[x]=1,p[++cnt]=x;
}
LL dfs(int pos, LL x)
{
    LL ans=0;
    for (int i=pos; i<=cnt; i++)
        ans+=x/p[i]-dfs(i+1,x/p[i]);
    return ans;
}
LL find(LL l, LL r, LL k)
{
    while (l<=r)
    {
        LL mid=l+r>>1;
        if ((mid-dfs(1,mid))<k) l=mid+1;
        else r=mid-1; 
    }
    return l;
}
int main()
{
    int T=ra(); int cse=0;
    while (T--)
    {
        n=ra(); m=ra(); k=ra();
        mp.clear(); cnt=0;
        getprime((LL)n); getprime((LL)m);
        printf("Case %d: %I64d\n",++cse, find(1LL,1000000000000000LL,(LL)k));
    }
    return 0;
}

 

posted @ 2017-02-23 20:34  ws_ccd  阅读(192)  评论(0编辑  收藏  举报