zoukankan      html  css  js  c++  java
  • HDU4135

    Co-prime  -- 欧拉函数+容斥

    题意

    给三个数,N,A,B,问区间[A,B]之间与N互质的数的个数,共有T组样例 (1<=T<=100, (1 <= A <= B <= 1015) and (1 <=N <= 109).)

    分析

    欧拉函数求的是1~n和n互质的个数,现在的问题求的是区间[A,B]与N互质的数的个数,根据数据范围显然不能直接求

    互质不可以直接求,将其转化为不互质的,[1,n]与n不互质的数即为,n的质因子的倍数(由算数基本定理可知),故可以转化为求[1 , A-1]、[1 , B]和N不互质的个数,但求不互质的过程中存在重复(如,质因子2,3的的倍数都有6),需要容斥(奇加偶减),可将所有质因子看成一串二进制编码,算出即可

    #include<bits/stdc++.h>
    #define ll long long
    
    using namespace std;
    
    const int maxn = 1e5+10;
    
    ll a[maxn], n, aa, b;
    int tot;
    
    void init(ll n)
    {
        tot=0;
        for(ll i=2;i*i<=n;i++)
        {
            if(n&&n%i==0)
            {
                while(n%i==0)
                {
                    n/=i;
                }
                a[tot++]=i;
            }
        }
        if(n>1) a[tot++]=n;
    }
    ll solve(ll x)
    {
        ll sum=0;
        for(ll i=1;i<(1<<tot);i++)
        {
            ll val=1;
            int cnt=0;
            for(ll j=0; j<tot; j++)
            {
                if(i&(1<<j))
                {
                    val*=a[j];
                    cnt++;
                }
            }
            if(cnt&1) sum+=x/val;
            else sum-=x/val;
        }
        return x-sum;
    }
    
    int main()
    {
        int t;
        int Case=1;
        scanf("%d", &t);
        while(t--)
        {
            scanf("%lld%lld%lld", &aa, &b, &n);
            init(n);
            printf("Case #%d: %lld
    ", Case++, solve(b)-solve(aa-1));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    vba中application.statusbar表示返回或设置状态栏的文字
    vba中counta函数
    vba事件程序
    遇到错误继续执行的语句on error resume next
    vba中字典的一些函数
    vba中如何调用字典
    range.value
    vba中with/end with
    vba中for循环可以用for each 变量 in 数组/单元格/sheet表
    需要学习的内容
  • 原文地址:https://www.cnblogs.com/Superwalker/p/8511162.html
Copyright © 2011-2022 走看看