poj 2773 Happy 2006

来源:互联网 发布:乐视员工获刑4年 知乎 编辑:程序博客网 时间:2024/05/21 08:58

题目来源:http://poj.org/problem?id=2773

勉强过!

#include <cstdio>#include <cstring>#include <iostream>using namespace std;typedef long long LL;const int MAXN = 1000010;//如果求,x, y的公约数,如果x = k*x1, y = k*y1,则:Gcd(x, y) = k*Gcd(x1, y1);//如果x = p*x1, 其中p为素数,并且y%p != 0, 则:Gcd(x, y) = Gcd(p*x1, y1) = Gcd(x1, y);int Revise_Gcd(int a, int b)//求公约数,这个效率最高{    if(a < b)        return Revise_Gcd(b, a);    if(b == 0)        return a;    else    {        if(!(a & 1))        {            if(!(b & 1))                return (Revise_Gcd(a >> 1, b >> 1)<<1);            else                return Revise_Gcd(a >> 1, b);        }        else        {            if(!(b&1))                return Revise_Gcd(a, b >> 1);            else                return Revise_Gcd(b, a-b);        }    }}int main(){    int m, k, i, num;    int IsPrime[MAXN];    while(~scanf("%d %d", &m, &k))    {        if(m == 1)        {            printf("%d\n", k);            continue ;        }        num = 0;        for(i = 1; i < m; ++i)            if(Revise_Gcd(i, m) == 1)                IsPrime[num++] = i;        k--;        printf("%lld\n", k/num*(LL)m + IsPrime[k%num]);    }    return 0;}


方法二,容斥原理+二分,非常之快!

//利用二分计算[1, 2^64]中每个x的因子不与m互素的个数y,那么x-y == k时,x就是答案#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int MAXN = 1000010;typedef __int64 LL;int NotPrime[MAXN], num;void Inite(int n){int i;num = 0;for (i = 2; i * i <= n; ++i){if(n%i == 0)NotPrime[num++] = i;while(n%i == 0)n /= i;}if(n != 1)NotPrime[num++] = n;}LL Binary_Search_Ans( LL n ){int i, j;LL tmp, sum, res = 0, k;for (i = 1; i < (1<<num); ++i)//容斥原理的模版{tmp = 0, sum = 1;for (j = 0; j < num; ++j){if(i & (1<<j))tmp++, sum *= NotPrime[j];}k = n/sum;if(tmp & 1)res -= k;elseres += k;}return n + res;}int main(){int m, k;LL iLeft, iRight, iMid, tmp;while (~scanf("%d %d", &m, &k)){Inite(m);iLeft = 1, iRight = (1LL << 60);while (iLeft < iRight){iMid = (iLeft + iRight)>>1;tmp = Binary_Search_Ans(iMid) ;if (tmp >= k)iRight = iMid;elseiLeft = iMid + 1;}printf("%I64d\n", iLeft);}return 0;}


0 0
原创粉丝点击