POJ2773Happy2006题解--数论好题

题目链接

https://cn.vjudge.net/problem/POJ-2773

题意:

求第\(k\)个与\(m\)互质的数

分析

因为\(gcd(a,b)=gcd(a+t * b,b)\)

所以在\([1,m-1]\)中与\(m\)互质的个数与在\([k \times m+1,(k+1) \times m-1]\)的互质(把上一个式子的\(b\)看成\(m\)一下就明白了)的个数都等于\(\phi (m)\)

然后直接暴力计算出\([1,m-1]\)与其互质的数,再根据周期搞一搞就好了

还有二分+容斥的方法,先挖个坑

代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <iostream>
#define ll long long 
#define ri register int 
using std::min;
using std::max;
template <class T>inline void read(T &x){
    x=0;int ne=0;char c;
    while(!isdigit(c=getchar()))ne=c==‘-‘;
    x=c-48;
    while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
    x=ne?-x:x;return ;
}
const int maxn=1000005;
const int inf=0x7fffffff;
int num[maxn];
int m,k,tot=0;
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int main(){
    while(scanf("%d %d",&m,&k)!=EOF){
        tot=0;
        for(ri i=1;i<=m;i++){if(gcd(m,i)==1)num[++tot]=i;}
        if(!(k%tot)){printf("%lld\n",1ll*(k/tot-1)*m+num[tot]);}//特判一下
        else printf("%lld\n",1ll*(k/tot)*m+num[k%tot]);
    }
    return 0;
}

POJ2773Happy2006题解--数论好题

上一篇:Java程序员秋招面经大合集(BAT美团网易小米华为中兴等)


下一篇:MVP实战心得—封装Retrofit2.0+RxAndroid+RxBus