现在的位置: 首页 > 综合 > 正文

HDU1659 欧拉函数+容斥原理 HDU1659 欧拉函数+容斥原理

2017年11月04日 ⁄ 综合 ⁄ 共 1709字 ⁄ 字号 评论关闭
 

HDU1659 欧拉函数+容斥原理

分类: 数论 58人阅读 评论(0) 收藏 举报

HDU1695

 

题意: 1~a, 1~b中挑出(x,y)满足gcd(x,y) = k , (x,y) 的对数 , a,b<=10^5

思路: gcd(x, y) == k 说明x,y都能被k整除但是能被k整除的未必gcd=k  , 必须还要满足

互质关系. 问题就转化为了求1~a/k 和 1~b/k间互质对数的问题

可以把a设置为小的那个数那么以y>x来保持唯一性(题目要求比如[1,3] = [3,1] )

接下来份两种情况:

1. y <= a , 那么对数就是 1~a的欧拉函数的累计和(容易想到)

2. y >= a , 这个时候欧拉函数不能用了,怎么做?  可以用容斥原理,y1~a互质对数问题转换为

y的质数因子在1~a范围内能整除的个数(质数分解和容斥关系)dfs一下即可.

 

  1. #include <iostream>  
  2. #include <stdio.h>  
  3. using namespace std;  
  4. #define N 100005  
  5. #define ll __int64  
  6.   
  7. ll eule[N];  
  8. int p[N][15];  
  9. int num[N];  
  10.   
  11. void init()  
  12. {  
  13.     int i,j;  
  14.     eule[1]=1;  
  15.     for(i=2;i<N;i++)//筛选法得到数的素因子及每个数的欧拉函数值  
  16.     {  
  17.         if(!eule[i])  
  18.         {  
  19.             for(j=i;j<N;j+=i)  
  20.             {  
  21.                 if(!eule[j])  
  22.                     eule[j]=j;  
  23.                 eule[j]=eule[j]*(i-1)/i;  
  24.                 p[j][num[j]++]=i;  
  25.             }  
  26.         }  
  27.         eule[i]+=eule[i-1];  
  28.     }  
  29. }  
  30.   
  31. ll DFS(int x,int MAX,int q)   //求MAX内与q不互质的个数  
  32. {  
  33.     int i;  
  34.     ll res=0;  
  35.     for (i=x;i<num[q];i++)  
  36.     {  
  37.         res+=MAX/p[q][i]-DFS(i+1,MAX/p[q][i],q);  
  38.     }  
  39.     return res;  
  40. }  
  41.   
  42. int main()  
  43. {  
  44.     int t,a,b,MAX,MIN,k,flag,i;  
  45.     __int64 res;  
  46.     init();  
  47.     scanf("%d",&t);  
  48.     flag=0;  
  49.     while(t--)  
  50.     {  
  51.         flag++;  
  52.         scanf("%d%d%d%d%d",&a,&a,&b,&b,&k);  
  53.         if(k==0)  
  54.         {  
  55.             printf("Case %d: 0\n",flag);  
  56.             continue;  
  57.         }  
  58.         MAX=a>b?a:b;  
  59.         MIN=a>b?b:a;  
  60.         MAX/=k;  
  61.         MIN/=k;  
  62.         res=eule[MIN];  
  63.         for(i=MIN+1;i<=MAX;i++)  
  64.         {  
  65.             res+=MIN-DFS(0,MIN,i);  
  66.         }  
  67.         printf("Case %d: %I64d\n",flag,res);  
  68.     }  
  69.     return 0;  
  70. }  

抱歉!评论已关闭.