首页 > 其他分享 >CF915G Coprime Arrays 题解

CF915G Coprime Arrays 题解

时间:2023-09-02 10:22:37浏览次数:47  
标签:lfloor right Arrays 题解 rfloor Coprime dfrac mod left

题意

给定 \(n, k\),对于所有的 \(m \in \left[1, k\right]\),求长度为 \(n\),值域为 \(\left[1,m \right]\) 且最大公约数为 \(1\) 的序列种数,对 \(10^9 + 7\) 取模。

(\(1 \le n,k \le 2 \times 10^6\))。

题解

设 \(f(d, m)\) 表示长度为 \(n\),值域为 \(\left[1,m \right]\) 且最大公约数为 \(1\) 的序列种数,\(g(d, m)\) 表示长度为 \(n\),值域为 \(\left[1,m \right]\) 且序列元素均为 \(d\) 的倍数即最大公约数为 \(d\) 的倍数的序列种数,那么有

\[\begin{aligned} g(d, m) &= \sum\limits_{d \mid h} f(h, m) \\ f(d, m) &= \sum\limits_{d \mid h} \mu\left(\dfrac{h}{d}\right) g(h, m) \end{aligned}\]

考虑计算 \(g(d, m)\),发现

\[g(d, m) = \left\lfloor\dfrac{m}{d}\right\rfloor^n \]

综上,可得

\[f(1, m) = \sum\limits_{i = 1}^{m} \mu\left(i\right)\left\lfloor\dfrac{m}{i}\right\rfloor^n \]

现在我们得到了答案的计算式,但是若对于每个 \(m\) 应用整除分块计算,复杂度为 \(\mathcal{O}(k \sqrt{k} \log n)\),若使用线性筛预处理出幂函数,那么复杂度为 \(\mathcal{O}(k \sqrt{k})\),均无法通过本题。

故考虑在 \(f(1, m - 1)\) 的基础上计算 \(f(1, m)\),考虑 \(f(1, m)\) 较 \(f(1, m - 1)\) 的差值均为 \(\left\lfloor\dfrac{m}{i}\right\rfloor\) 的改变引起的,而对于每个 \(i\),只有 \(m\) 增大为 \(i\) 的倍数时该值才会改变,故答案共会改变 \(\mathcal{O}(k \ln k)\) 次。形式化的,有

\[\begin{aligned} f(1, m) &= f(1, m - 1) + \left(f(1, m) - f(1, m - 1)\right) \\ &= f(1, m - 1) + \left(\sum\limits_{i = 1}^{m} \mu\left(i\right)\left\lfloor\dfrac{m}{i}\right\rfloor^n - \sum\limits_{i = 1}^{m - 1} \mu\left(i\right)\left\lfloor\dfrac{m - 1}{i}\right\rfloor^n\right) \\ &= f(1, m - 1) + \sum\limits_{i = 1}^{m}\mu\left(i\right)\times\left(\left\lfloor\dfrac{m}{i}\right\rfloor^n - \left(\left\lfloor\dfrac{m}{i}\right\rfloor - 1\right)^n\right) \end{aligned}\]

而 \(\left\lfloor\dfrac{m}{i}\right\rfloor^n - \left(\left\lfloor\dfrac{m}{i}\right\rfloor - 1\right)^n\) 的取值只有 \(i \mid m\) 时才不为 \(0\),故上式后半部分在 \(m\) 取遍 \(\left[1, k\right]\) 时产生贡献的次数共为 \(\mathcal{O}(k \ln k)\) 次。

对于每个数,预处理其因子,在 \(m\) 增长后,对于当前 \(m\) 的所有因子 \(i\),\(\left\lfloor\dfrac{m}{i}\right\rfloor\) 的值均会增长 \(1\),将答案累加 \(\mu\left(i\right)\times\left(\left\lfloor\dfrac{m}{i}\right\rfloor^n - \left(\left\lfloor\dfrac{m}{i}\right\rfloor - 1\right)^n\right)\) 即可。

使用线性筛预处理出幂函数,在 \(n,k\) 同阶的情况下,总复杂度为 \(\mathcal{O}(n \log n)\),可以通过本题。

Code

#include <bits/stdc++.h>

typedef int valueType;
typedef std::vector<valueType> ValueVector;
typedef std::vector<ValueVector> ValueMatrix;
typedef std::vector<bool> bitset;

constexpr valueType MOD = 1e9 + 7;

template<typename T1, typename T2, typename T3 = valueType>
void Inc(T1 &a, T2 b, const T3 &mod = MOD) {
    a = a + b;

    if (a >= mod)
        a -= mod;
}

template<typename T1, typename T2, typename T3 = valueType>
T1 sub(T1 a, T2 b, const T3 &mod = MOD) {
    return a - b < 0 ? a - b + mod : a - b;
}

template<typename T1, typename T2, typename T3 = valueType>
T1 mul(T1 a, T2 b, const T3 &mod = MOD) {
    return (long long) a * b % mod;
}

template<typename T1, typename T2, typename T3 = valueType>
void Mul(T1 &a, T2 b, const T3 &mod = MOD) {
    a = (long long) a * b % mod;
}

template<typename T1, typename T2, typename T3 = valueType>
T1 pow(T1 a, T2 b, const T3 &mod = MOD) {
    T1 result = 1;

    while (b > 0) {
        if (b & 1)
            Mul(result, a, mod);

        Mul(a, a, mod);
        b = b >> 1;
    }

    return result;
}

class LineSieve {
public:
    typedef std::vector<valueType> container;

private:
    valueType N, M;
    container prime;
    bitset isPrime;
    container Mobius, Power;
    ValueMatrix Factor;

public:
    LineSieve(valueType n, valueType m) : N(n), M(m), prime(), isPrime(n + 1, true), Mobius(n + 1, 1), Factor(n + 1),
                                          Power(n + 1, 1) {
        isPrime[0] = isPrime[1] = false;
        Mobius[1] = 1;
        Power[0] = 0;
        Power[1] = 1;

        for (valueType i = 2; i <= N; ++i) {
            if (isPrime[i]) {
                prime.push_back(i);

                Mobius[i] = -1;

                Power[i] = ::pow(i, M);
            }

            for (auto const &iter: prime) {
                valueType const t = i * iter;

                if (t > N)
                    break;

                isPrime[t] = false;

                Power[t] = mul(Power[i], Power[iter]);

                if (i % iter == 0) {
                    Mobius[t] = 0;

                    break;
                } else {
                    Mobius[t] = -Mobius[i];
                }
            }

            if (Mobius[i] < 0)
                Mobius[i] += MOD;
        }

        for (valueType i = 1; i <= N; ++i)
            for (valueType j = i; j <= N; j += i)
                Factor[j].push_back(i);
    }

    valueType operator()(valueType n) const {
        return Mobius[n];
    }

    valueType pow(valueType n) const {
        return Power[n];
    }

    const ValueVector &fact(valueType n) const {
        return Factor[n];
    }
};

int main() {
    valueType N, K;

    std::cin >> N >> K;

    LineSieve const sieve(K, N);

    ValueVector ans(K + 1, 0);

    for (valueType i = 1; i <= K; ++i) {
        ans[i] = ans[i - 1];

        for (auto const &iter: sieve.fact(i))
            Inc(ans[i], mul(sieve(iter), sub(sieve.pow(i / iter), sieve.pow(i / iter - 1))));
    }

    valueType result = 0;

    for (valueType i = 1; i <= K; ++i)
        Inc(result, ans[i] ^ i);

    std::cout << result << std::endl;
}

标签:lfloor,right,Arrays,题解,rfloor,Coprime,dfrac,mod,left
From: https://www.cnblogs.com/User-Unauthorized/p/solution-CF915G.html

相关文章

  • [NOI2021] 轻重边题解
    题目传送门一眼数据结构考虑树上有什么数据结构支持\(x\)到\(y\)节点的修改和查询,那就是:树链剖分。那么这道树链剖分的题有个\(trick\):边点转换&染色法,对于每次修改,考虑将修改路径上的点全部染上一种独一无二的颜色,而查询的时候,就查询路径上相邻的相同的颜色节点个数即可......
  • 爱思创模拟06试题易错题解析
    错误原因:漏项正确答案:C按节点数分类穷举 举一反三:  错误原因:处理三个空位的时候,情况考虑的太多正确答案:分情况计算,先枚举4个人共A(4,4)=24种情况,再考虑剩下两个空位置的情况,即A(5,2)=20种情况,最终答案就是24*20=480种举一反三:  错误原因:不会计算时间复杂度......
  • 题解 正妹吃月饼
    题目链接由于每个质量的月饼只有一个,并且质量恰好是2的整数倍,所以考虑将一个质量看成一个二进制位。那么也就是说,我们要构造一个二进制数\(x\),使得\(x\)的\(1\)的个数最多,且满足\(a\lex\leb\)。那么这就可以用类似数位\(DP\)的思路来做,从高位往低位看,若\(a_i=b_i=1......
  • NOIP2012提高组初赛易错题解析
    一.3. 错误原因:忘记了解析:Intel是全球最大的CPU厂商,AMD是世界上首个研发出7纳米CPU的厂商 6.错误原因:忘记了解析:ENIAC是世界上首台计算机,属于第一代计算机,即电子管计算机 10.错误原因:选项理解错误解析:A由蝙蝠,发明雷达是正确的,B因特网的发明与蜘蛛网无关,只是形......
  • NOIP2011提高组初赛易错题解析
    一.7.错误原因:不知道解析:快速排序在理论上最低的时间复杂度为O(n),但实际最低的时间复杂度为O(nlogn) 二.1.错误原因:漏项了解析:这棵树最少有12层,但题目是问可能是几层,所以还可能是2011层 5.错误原因:漏了一种情况解析:这道题的树有两种,所以答案也有两种 ......
  • 牛客小白月赛77 C题解 | 小Why的商品归位
    原题链接先不考虑车子的容量问题,因为结束位置保证是在起始位置之后的,那我们从前往后扫,发现是可以知道每个点时的车内的商品。但是现在有了容量限制,我们怎么办呢,如果对于一段,k都是大于每个点的货物量时,可以一趟装完,但是如果大于k就需要不知一次,可以发现所需的其实是该段的最大......
  • CF1626F A Random Code Problem 题解
    题意给定长度为\(n\)的数组\(a\)和一个整数\(k\),执行下面的代码:longlongans=0;//定义一个初始值为0的长整型变量for(inti=1;i<=k;i++){ intidx=rnd.next(0,n-1);//生成一个介于0到n-1的随机数(含0和n-1) //每个数被选中的概率是相同的 an......
  • Maximum Diameter 题解
    MaximumDiameter题目大意定义长度为\(n\)的序列\(a\)的权值为:所有的\(n\)个点的第\(i\)个点的度数为\(a_i\)的树的直径最大值,如果不存在这样的树,其权值为\(0\)。给定\(n\),求所有长度为\(n\)的序列的权值和。思路分析\(n\)个点的树的边数为\(n-1\),总度数......
  • 【题解】Harbour.Space Scholarship Contest 2023-2024 D,E,F(CF1864)
    D.MatrixCascade题目描述:有一个大小为\(n\timesn\)的矩阵,由0和1组成。行的编号从上到下依次为\(1\)到\(n\),列的编号从左到右依次为\(1\)到\(n\)。第\(x\)行与第\(y\)列交叉处的单元格记为\((x,y)\)。水月想把矩阵的所有元素都变成0。她可以一步完成以下操作:选择任意......
  • kde桌面“屏幕边缘”无法触发问题解决
    鼠标放到屏幕边缘无法触发效果,搜索后是设置问题。解决办法:系统设置——硬件——显卡与显示器——显示特效合成器,勾选允许应用阻止显示特效合成,然后右下角点击应用参考:https://www.cnblogs.com/pipci/p/14870650.html......