• 2019牛客多校第三场D BigInteger——基础数论


    题意:

    用  $A(n)$ 表示第 $n$ 个只由1组成分整数,现给定一个素数 $p$,求满足 $1 leq ileq n, 1 leq j leq m, A(i^j) equiv 0(mod p)$ 的 $(i, j)$ 对数。

    分析:

    $11...11 = frac{10^n-1}{9} equiv 0(mod p)$ 等价于 $10^n equiv 1(mod 9p)$,当 $p eq 2,5$ 时,有 $gcd(10, 9p)=1$,因此 $10^{phi(9p)} equiv 1(mod 9p)$。我们需要找到满足等式最小的数 $d$,也是循环节,显然 $d | phi (9p)$,直接枚举 $phi(9p)$ 的约数验证即可。

    找到循环节 $d$ 后,我们需要知道有多少对 $(i, j)$ 满足 $d | i^j$.

    对 $d$ 做质因数分解, $d = p_1^{k_1}p_2^{k_2}...p_l^{k_l}$,考虑 $j$ 固定的时候,$i$ 需要满足什么条件?$i$ 必须是 $g = p_1^{left lceil frac{K_1}{j} ight ceil} p_2^{left lceil frac{K_2}{j} ight ceil} ... p_l^{left lceil frac{K_l}{j} ight ceil}$ 的倍数,因此共有 $frac{n}{g}$ 个合法的 $i$。

    由于 $k_i leq 30$,所以 $j$ 增加到30以上和 $j=30$ 的结果是一样的,枚举 $j$ 从1到30,分别计算 $g$ 即可。

    当 $p=2,5$ 的时候,显然答案为0.

    $phi(9p)$ 也不必用欧拉函数计算,当 $p eq 3$ 时,3与p互素,根据欧拉函数的积性,$phi (9p) = phi (9)phi (p) = 6(p-1)$.

    由于快速幂会爆long long,需要用__int128(血的教训啊,wa了好多发,枯了)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long ll;
    
    ll p, m ,n;
    map<ll, ll>ma;
    
    __int128  qpow(__int128  a, __int128  b, __int128  p)
    {
        __int128  res = 1;
        while(b)
        {
            if(b & 1)  res = res * a % p;
            a = (a * a) % p;  //a*a会爆long long
            b >>= 1;
        }
        return res;
    }
    
    ll  qpow2(ll  a, ll  b)
    
    {
        ll  res = 1;
        while(b)
        {
            if(b & 1)  res = res * a;
            a = a * a;
            b >>= 1;
        }
        return res;
    }
    
    //约数枚举O(√n)
    ll divisor(ll n, ll p)
    {
        vector<ll>res;
        for (ll i = 1; i * i <= n; i++)
        {
            if (n % i == 0)
            {
                //printf("i:%lld
    ", i);
                if(qpow(10, i, 9*p) % (9*p) == 1)  return i;
                if(i != n / i)  res.push_back(n / i);
            }
        }
        for(ll i = res.size()-1;i >= 0;i--)
        {
            // printf("i:%lld
    ", res[i]);
             if(qpow(10, res[i], 9*p) % (9*p) == 1)  return res[i];
        }
        return 0;
    }
    
    //整数分解O(√n)
    void prime_factor(ll n)
    {
        for (int i = 2; i * i<= n; i++)
        {
            while (n % i == 0)
            {
                ++ma[i];
                n /= i;
            }
        }
        if (n != 1)  ma[n] = 1;        //最多只有一个素因数大于√n
    }
    
    
    //j固定的情况下的对数
    ll  OneJ(int j)
    {
        ll res = 1;
        for(auto it = ma.begin();it != ma.end();it++)
        {
            res *= qpow2((*it).first, (ll)ceil((*it).second * 1.0 / j));
        }
        return n / res;
    }
    
    
    int  main()
    {
        int T;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%lld%lld%lld", &p, &n, &m);
            //int fai = euler_phi(9*p);
            ll k;
            if(p == 2 || p == 5)
            {
                printf("0
    ");
                continue;
            }
    
            if(p == 3)
            {
                k =  divisor(18, p);
            }
            else  k = divisor(6*(p-1), p);  //printf("k:%lld
    ", k);
    
            if(k == 0)  printf("0
    ");
            else
            {   ma.clear();
                ll res = 0;
                prime_factor(k);  //printf("k:%lld
    ", k);
    
                if(m < 30)
                {
                     for(int i = 1;i <= m;i++)  res += OneJ(i);
                }
                else
                {
                    for(int i = 1;i <= 29;i++)  res += OneJ(i);
                    int tmp = OneJ(30);
                    res += tmp * (m - 29);
                }
                printf("%lld
    ", res);
            }
        }
        return 0;
    }
  • 相关阅读:
    [Scoi2010]游戏
    HDU3415(单调队列)
    POJ1221(整数划分)
    POJ1050(dp)
    POJ2479(dp)
    HDU1864(背包)
    HDU1175(dfs)
    STL_string.vector中find到的iterator的序号
    Qt532.数值转为16进制(并填充)
    异常处理.VC++
  • 原文地址:https://www.cnblogs.com/lfri/p/11258814.html
Copyright © 2020-2023  润新知