• hdu (欧拉函数+容斥原理) GCD


    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1695

    看了别人的方法才会做 参考博客http://blog.csdn.net/shiren_Bod/article/details/5787722

    题意 a,b,c,d,k五个数,a与c可看做恒为1,求在a到b中选一个数x,c到d中选一个数y,使得gcd(x,y)等于k,求x和y有多少对。

    首先可以想到选取的必是k的倍数,假设是x和y倍,则x和y一定是互质的在,那么就变成了求1到b/k和1到d/k的之间的互质的组数。

    假设d大于b的话,可以从1到d枚举i,当i小于等于b的时候,互质的数的个数就是其欧拉函数,当i大于b的时候就不是欧拉函数了,因为与i互质的

    数要不大于b,那么可以逆向思维一下,求在不大于b的数中与i互质的数,这里就要用到容斥原理,

    容斥原理大致是如果被计数的事物有A、B两类,那么,A类B类元素个数总和= 属于A类元素个数+ 属于B类元素个数—既是A类又是B类的元素个数。

    那么在这道题里就是;  区间中与i不互质的个数 = (区间中i的每个质因数的倍数个数)-(区间中i的每两个质因数乘积的倍数)+(区间中i的每3个质因数的成绩的倍数个数)-(区间中i的每4个质因数的乘积)+~~~~~(这个容斥想了好一会儿才想通)

    然后用dfs求容斥原理,看了别人代码才看懂,还是太菜。

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 typedef long long ll;
     5 const int maxn=100010;
     6 int num[maxn],p[maxn][50];
     7 ll enul[maxn];
     8 void great(){
     9     int i,j;
    10     enul[1]=1;
    11     for (i=2;i<maxn;i++){
    12         if (!enul[i]){
    13             for (j=i;j<maxn;j+=i){
    14                 if (!enul[j])
    15                     enul[j]=j;
    16                 enul[j]=enul[j]*(i-1)/i;
    17                 p[j][num[j]++]=i;
    18             }
    19         }
    20     }
    21 }
    22 int dfs(int a,int b,int c){
    23     int sum=0,i;
    24     for (i=a;i<num[c];i++)
    25         sum+=b/p[c][i]-dfs(i+1,b/p[c][i],c);
    26     return sum;
    27 }
    28 int main()
    29 {
    30     int n,a,b,c,d,k,i,t=1;
    31     great();
    32     scanf("%d",&n);
    33     while (n--){
    34         scanf("%d %d %d %d %d",&a,&b,&c,&d,&k);
    35         if(k==0){
    36             printf("Case %d: 0
    ",t++);
    37             continue;
    38         }
    39         b=b/k;d=d/k;
    40         if (b>d) swap(b,d);
    41         ll ans=0;
    42         for (i=1;i<=b;i++)
    43             ans+=enul[i];
    44         for (i=b+1;i<=d;i++){
    45             ans+=b-dfs(0,b,i);
    46         }
    47         printf("Case %d: %I64d
    ",t++,ans);
    48     }
    49 
    50     return 0;
    51 }
  • 相关阅读:
    32位和64位系统区别及int字节数
    进程的三种状态及转换
    已知二叉树的前序/后序遍历和中序遍历,求后序/前序遍历
    一步一步写算法
    Ubuntu中APache+mod_pyhon
    JAVA SOCKET
    TCP连接 断开
    mfc 创建一个C++ 类
    mfc 类的析构函数
    mfc 类对象的引用
  • 原文地址:https://www.cnblogs.com/JJCHEHEDA/p/5267251.html
Copyright © 2020-2023  润新知