UESTC 1552(欧拉函数)

来源:互联网 发布:库房软件 编辑:程序博客网 时间:2024/06/05 10:47
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<queue>using namespace std;#define lc l,m,index<<1#define rc m+1,r,index<<1|1#define ll long long#define inf 0x3f3f3f3f#define N 10005int n,m,ans;int prime[N],sum;struct Zys{int num,cnt;}zys[N];int cnt;int Eular(int num)//欧拉函数{ int i; int ret=num; for(i=0;i<sum&&prime[i]*prime[i]<=num;++i) { if(num%prime[i]==0) { ret-=ret/prime[i]; while(num%prime[i]==0)num/=prime[i]; if(num==1)break; } } if(num!=1)ret-=ret/num; return ret; }void init()//筛选素数{int i,j,flag;prime[0]=2;sum=1;for(i=3;i<=100000;i++){flag=1;for(j=0;j<sum&&prime[j]*prime[j]<=i;j++){if(i%prime[j]==0){flag=0;break;}}if(flag)prime[sum++]=i;}}void fj(int num)//分解n{int i;for(i=0;i<sum&&prime[i]*prime[i]<=num;i++){if(num%prime[i]==0){zys[cnt].num=prime[i];zys[cnt].cnt=1;num/=prime[i];while(num%prime[i]==0){zys[cnt].cnt++;num/=prime[i];}cnt++;}}if(num!=1){zys[cnt].num=num;zys[cnt].cnt=1;cnt++;}}int pm(int x,int y){int ret=1;while(y--)ret*=x;return ret;}void dfs(int dep,int num)//枚举n的约数{if(dep==cnt){if(num>=m)ans+=Eular(n/num);return;}int i;for(i=0;i<=zys[dep].cnt;i++)dfs(dep+1,num*pm(zys[dep].num,i));}int main(){init();int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);cnt=0;ans=0;fj(n);dfs(0,1);printf("%d\n",ans);}return 0;}

原创粉丝点击