• HDU 1695 GCD ★(容斥原理+欧拉函数)


    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1695 题目大意:求[1..b]中的x和[1..d]中的y有多少gcd(x,y) = k. 思路: 预备知识:容斥原理求数区间[1..r]中与n互质的数的个数.   Here 要求gcd(x,y) = k,则等价于求 gcd(x/k,y/k) = 1.所以问题转化成求[1..b/k]和[1..d/k]中有多少对gcd(x,y) = 1. 又因为此题要求gcd(1,3)和gcd(3,1)算一个,所以我们不妨按x < y来求. 接下来,我们枚举x的值,然后便转化为求[x..d/k]区间中与x互质的数的个数,用容斥原理解决. [x..d/k] = [1..d/k] - [1..x-1],[1..d/k]我们用上面的容斥原理方法就可以解决,[1..x-1]虽然也可以用容斥,但速度较慢,明显可以用更快的欧拉函数做。  
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #define MID(x,y) ((x+y)>>1)
    
    using namespace std;
    
    typedef long long LL;    //max long long == 9223372036854775807LL
    
    LL phi(LL n)
    {
        if (n == 1) return 0;
        LL i,sum=n;
        for(i=2; i*i<=n; i++)
        {
            if(n%i==0)
            {
                sum = sum / i * (i-1);
                do
                {
                    n/=i;
                }
                while(n%i==0);
            }
        }
        if(n>1) sum = sum / n * (n - 1);
        return sum;
    }
    
    int solve(int r, int n){
        if (r == 0) return 0;
        int res = 0;
        vector  p;
        for (int i = 2; i * i <= n; i ++){
            if (n % i == 0){
                p.push_back(i);
                while(n % i == 0){
                    n /= i;
                }
            }
            if (n == 1) break;
        }
        if (n > 1)  p.push_back(n);
        for (int msk = 1; msk < (1 << p.size()); msk ++){
            int mult = 1, bit = 0;
            for (int i = 0; i < p.size(); i ++){
                if (msk & (1 << i)){
                    bit ++;
                    mult *= p[i];
                }
            }
            int cur = r / mult;
            if (bit % 2 == 1){
                res += cur;
            }
            else{
                res -= cur;
            }
        }
        return r - res;
    }
    
    int main(){
        int t, caseo = 1;
        cin>>t;
        while(t --){
            int a,b,c,d,k;
            cin>>a>>b>>c>>d>>k;
            if (k == 0){
                cout<<"Case "< d){
                int tmp = d;
                d = b;
                b = tmp;
            }
            LL ans = 0;
            for (int i = 1; i <= b; i ++){
                ans += (LL)solve(d, i) - phi(i);
            }
            cout<<"Case "<
    举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG
  • 相关阅读:
    javascript实现网页分享至朋友圈功能
    Vue中全局过滤器期与局部过滤器期的使用
    vue中添加与删除,关键字搜索
    vue生命周期
    4种常用的Ajax请求方式
    CSS 基础总结
    BEM思想之彻底弄清BEM语法
    学习前端过程中用到的资料
    深入理解,函数声明、函数表达式、匿名函数、立即执行函数、window.onload的区别.
    html基础
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/4113965.html
Copyright © 2020-2023  润新知