首页 > 学院 > 开发设计 > 正文

GCD Again HDU - 1787 (欧拉函数 or 容斥原理)

2019-11-06 07:01:04
字体:
来源:转载
供稿:网友
Do you have spent some time to think and try to solve those unsolved PRoblem after one ACM contest? No? Oh, you must do this when you want to become a "Big Cattle". Now you will find that this problem is so familiar: The greatest common divisor GCD (a, b) of two positive integers a and b, sometimes written (a, b), is the largest divisor common to a and b. For example, (1, 2) =1, (12, 18) =6. (a, b) can be easily found by the Euclidean algorithm. Now I am considering a little more difficult problem: Given an integer N, please count the number of the integers M (0<M<N) which satisfies (N,M)>1. This is a simple version of problem “GCD” which you have done in a contest recently,so I name this problem “GCD Again”.If you cannot solve it still,please take a good think about your method of study. Good Luck! InputInput contains multiple test cases. Each test case contains an integers N (1<N<100000000). A test case containing 0 terminates the input and this test case is not to be processed. OutputFor each integers N you should output the number of integers M in one line, and with one line of output for each line in input. Sample Input
240Sample Output
01
欧拉函数
#include <iostream>#include <cstdio>#include <cmath>#include <queue>#include <stack>#include <map>#include <algorithm>#include <vector>#include <string>#include <cstring>#include <sstream>#define INF 100000000using namespace std;int n;const int size=1000000;int vis[1000000];int solve(){    int ans=1;    int tmp=int(sqrt(n)+0.5);    for(int i=2;i<=tmp;i++)    {        if(n%i==0)        {            n/=i;            ans*=(i-1);        }        while(n%i==0)        {            n/=i;            ans*=i;        }    }    if(n>1)    {        ans*=n-1;    }    return ans;}int main(){    while(scanf("%d",&n)==1)    {        int a=n;        if(n==0) return 0;        int cnt=0;        int ans=solve();        ans=a-1-ans;        printf("%d/n",ans);    }    return 0;}
容斥原理
#include <iostream>#include <cstdio>#include <cmath>#include <queue>#include <stack>#include <map>#include <algorithm>#include <vector>#include <string>#include <cstring>#include <sstream>#define INF 100000000using namespace std;int n;int j;int p[10000];int s;void solve(int cur,int m,int k){    if(cur==j)    {        if(m==1) return;        if(k%2==1) s+=n/m-1;        else s-=n/m-1;    }    else    {        solve(cur+1,m,k);        solve(cur+1,m*p[cur],k+1);    }}int main(){    while(scanf("%d",&n)==1)    {        if(n==0) return 0;        j=0;        int nn=n;        for(int i=2;i*i<=nn;i++)        {            if(nn%i==0)            {                p[j++]=i;                while(nn%i==0)                {                    nn/=i;                }            }        }        if(nn>1)        {            p[j++]=nn;        }        s=0;        solve(0,1,0);        printf("%d/n",s);    }    return 0;}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表