首页 > 其他分享 >F - Subsequence LCM

F - Subsequence LCM

时间:2024-04-19 15:12:56浏览次数:17  
标签:元素 cdots leq Subsequence alpha LCM mathrm

F - Subsequence LCM

Problem Statement

You are given a sequence of positive integers $A=(A_1,A_2,\dots,A_N)$ of length $N$ and a positive integer $M$. Find the number, modulo $998244353$, of non-empty and not necessarily contiguous subsequences of $A$ such that the least common multiple (LCM) of the elements in the subsequence is $M$. Two subsequences are distinguished if they are taken from different positions in the sequence, even if they coincide as sequences. Also, the LCM of a sequence with a single element is that element itself.

Constraints

  • $1 \leq N \leq 2 \times 10^5$
  • $1 \leq M \leq 10^{16}$
  • $1 \leq A_i \leq 10^{16}$
  • All input values are integers.

Input

The input is given from Standard Input in the following format:

$N$ $M$
$A_1$ $A_2$ $\ldots$ $A_N$

Output

Print the answer.


Sample Input 1

4 6
2 3 4 6

Sample Output 1

5

The subsequences of $A$ whose elements have an LCM of $6$ are $(2,3),(2,3,6),(2,6),(3,6),(6)$; there are five of them.


Sample Input 2

5 349
1 1 1 1 349

Sample Output 2

16

Note that even if some subsequences coincide as sequences, they are distinguished if they are taken from different positions.


Sample Input 3

16 720720
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

Sample Output 3

2688

 

解题思路

  一些技巧。要对 $a_1, \ldots, a_n$ 求 $\gcd$ 或 $\mathrm{lcm}$,先质因数分解,使得每个 $a_i$ 都有共同的质因子 $P$(不存在则用 $P^0$ 表示):

\begin{align*}
a_1 & = P_{1}^{\alpha_{1,1}} P_{2}^{\alpha_{1,2}} \cdots P_{k}^{\alpha_{1,k}} \\
a_2 & = P_{1}^{\alpha_{2,1}} P_{2}^{\alpha_{2,2}} \cdots P_{k}^{\alpha_{2,k}} \\
& \;\;\vdots \\
a_i & = P_{1}^{\alpha_{i,1}} P_{2}^{\alpha_{i,2}} \cdots P_{k}^{\alpha_{i,k}} \\
& \;\;\vdots \\
a_n & = P_{1}^{\alpha_{n,1}} P_{2}^{\alpha_{n,2}} \cdots P_{k}^{\alpha_{n,k}} \\
\end{align*}

  那么就有:

\begin{align*}
\gcd(a_1, \ldots, a_n) &= P_{1}^{\min\{\alpha_{i,1}\}} P_{2}^{\min\{\alpha_{i,2}\}} \cdots P_{k}^{\min\{\alpha_{i,k}\}} \\
\mathrm{lcm}(a_1, \ldots, a_n) &= P_{1}^{\max\{\alpha_{i,1}\}} P_{2}^{\max\{\alpha_{i,2}\}} \cdots P_{k}^{\max\{\alpha_{i,k}\}}
\end{align*}

  由于子序列的 $\mathrm{lcm}$ 等于确定的 $m$,所以对 $m$ 进行质因数分解,有 $m = P_{1}^{\alpha_{1}} P_{2}^{\alpha_{2}} \cdots P_{k}^{\alpha_{k}}$,容易知道在 $10^{16}$ 内一个数最多有 $13$ 个不同的质因子,因此这里的 $k$ 最大为 $13$。同时这样的子序列中每个元素必然满足 $a_i \mid m$,因此一开始先把 $a_i \nmid m$ 的元素删掉,那么剩下的元素必定都能表示成 $P_{1}^{\beta_{1}} P_{2}^{\beta_{2}} \cdots P_{k}^{\beta_{k}}$,且 $\beta_{i} \leq \alpha_{i}$。

  根据上面提到求 $\mathrm{lcm}$ 的技巧,如果每个 $P_{i}$ 都有 $\max\{\beta_i\} = \alpha_i$,那么该子序列的 $\mathrm{lcm}$ 才能为 $m$。也就是说选出来的子序列中,在每一个 $P_i$ 上都至少存在一个元素该项的次幂为 $\alpha_i$。为此我们可以用 $k$ 位的二进制进行状态压缩,对于每一个元素,如果该元素质因数分解后 $P_i$ 项的次幂恰好是 $\alpha_i$,那么置第 $i$ 位为 $1$,否则置为 $0$。

  所以现在的问题变成了有多少种选择方案,使得选出来元素对应的二进制状态的按位或等于 $2^{k}-1$(即 $k$ 个位均为 $1$)。可以用 dp 解决,定义 $f(i,j)$ 表示从前 $i$ 个元素中选出状态按位或等于 $j$ 的方案数量。考虑从 $f(i,j)$ 可以转移到哪些状态,状态转移方程为 $f(i+1,j) \mathrm{+}\mathrm{=} f(i,j)$(不选择第 $i$ 个元素);$f(i+1,j \mid \mathrm{st}_i) \mathrm{+}\mathrm{=} f(i,j)$(选择第 $i$ 个元素,$a_i$ 的状态表示为 $\mathrm{st}_i$)。

  这样做的时间复杂度是 $O(n \cdot 2^{13})$,会超时。注意到最多有 $2 \cdot 10^5$ 个元素,而所有元素的状态最多有 $2^{13}$ 种,因此我们可以统计状态 $i$ 的数量表示为 $\mathrm{cnt}_i$。那么 $f(i,j)$ 表示从前 $i$ 个状态中选出按位或等于 $j$ 的方案数量。状态转移方程为 $f(i+1,j) \mathrm{+}\mathrm{=} f(i,j)$;$f(i+1,j \mid i) \mathrm{+}\mathrm{=} \left(2^{\mathrm{cnt}_i} - 1\right) \cdot f(i,j)$。

  我的代码实现是通过类似 01 背包的方式优化掉第一维,预处理出 $2^i$。直接用 $O(\sqrt{m})$ 的复杂度质因数分解 $m$。还有要记得特判 $m=1$ 的情况。

  AC 代码如下,时间复杂度为 $O(\sqrt{m} + 2^{2 \cdot 13})$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 2e5 + 5, M = 1 << 13, mod = 998244353;

int cnt[M];
int f[M];
int p[N];

int main() {
    int n;
    LL m;
    scanf("%d %lld", &n, &m);
    vector<LL> fs;
    LL t = m;
    for (LL i = 2; i * i <= t; i++) {
        if (t % i == 0) {
            LL p = 1;
            while (t % i == 0) {
                p *= i;
                t /= i;
            }
            fs.push_back(p);
        }
    }
    if (t > 1) fs.push_back(t);
    for (int i = 1; i <= n; i++) {
        LL x;
        scanf("%lld", &x);
        if (m % x) continue;
        int t = 0;
        for (int j = 0; j < fs.size(); j++) {
            if (x % fs[j] == 0) t |= 1 << j;
        }
        cnt[t]++;
    }
    p[0] = 1;
    for (int i = 1; i <= n; i++) {
        p[i] = p[i - 1] * 2 % mod;
    }
    f[0] = 1;
    for (int i = 0; i < 1 << fs.size(); i++) {
        if (!cnt[i]) continue;
        for (int j = (1 << fs.size()) - 1; j >= 0; j--) {
            f[j | i] = (f[j | i] + (p[cnt[i]] - 1ll) * f[j]) % mod;
        }
    }
    printf("%d", f[(1 << fs.size()) - 1] - (m == 1));
    
    return 0;
}

 

参考资料

  Editorial - AtCoder Beginner Contest 349:https://atcoder.jp/contests/abc349/editorial/9801

  ABC349F题 Subsequence LCM讲解(DP暴力做法 or 高维前缀和):https://www.bilibili.com/video/BV1jr42157Fa/

标签:元素,cdots,leq,Subsequence,alpha,LCM,mathrm
From: https://www.cnblogs.com/onlyblues/p/18144463

相关文章

  • [491] Non-decreasing Subsequences
    算法助手用户:这个题目有什么好的思路吗?“Givenanintegerarraynums,returnallthedifferentpossiblenon-decreasingsubsequencesofthegivenarraywithatleasttwoelements.Youmayreturntheanswerinanyorder.”我的代码是这样的:/**@lcapp=leetcod......
  • 【数论】最大公因数和最小公倍数(GCD和LCM)
    最大公因数(GCD)两个数的最大公因数很好做,使用内置的库函数即可,注意x和y的类型要相同。llgcd=__gcd(x,y);如果要求多个数的最大公因数,那么初始化为0(因为根据定义,0和任何数x的gcd都是x,所以0是gcd操作的幺元),然后分别进行gcd即可。llgcd=0;for(inti=1;i<=n;++i)......
  • CF1817A Almost Increasing Subsequence 题解
    题面。2023.5.18修正关于前缀和数组的说法,与代码适配的思路。题意给定长度为\(n\)一个序列\(a\)以及\(q\)次询问,每次询问给出\(l\)和\(r\),要求找出序列\(a\)在\([l,r]\)内最长的几乎递增子序列。对于几乎递增的定义:如果一个序列中不存在连续的三个数\(x\),\(y\)......
  • D. Inaccurate Subsequence Search
    原题链接题解明确每个变量的意义code#include<bits/stdc++.h>#definelllonglongusingnamespacestd;lla[200005];intmain(){llt;cin>>t;while(t--){map<ll,ll>b;//b[x]代表数组b中x的使用情况,大于0代表还有剩余,等于0代表刚好借满......
  • AI绘画:使用ComfyUI结合LCM进行实时绘图:开启AI艺术创作新篇章
    在数字艺术的世界里,ComfyUI和LCM(LatentContextualModulation)的结合为艺术家和设计师们提供了一个强大的实时绘图工具。LCM是一种先进的技术,它能够实时地将用户的输入和反馈融入到图像生成过程中,从而创造出动态变化的艺术作品。本文将作为一篇教程,引导你如何使用ComfyUI结合LC......
  • #线段树,模拟费用流#CF280D k-Maximum Subsequence Sum
    题目给定一个大小为\(n\)的序列,要求支持单点修改和查询区间内至多\(k\)个不交子区间之和的最大值(可以不取)分析考虑源点向每个点、每个点向汇点流流量1费用0的边,每个点向右边的点流流量1费用\(a_i\)的边,流量最大为\(k\),这样构建出一个费用流的模型。很显然,退流相当于给区......
  • LeetCode in Python 300. Longest Increasing Subsequence (最长递增子序列)
    求最长递增子序列是深度优先搜索(DFS)的一种应用,有两种比较好的方法可以解决。第一种是动态规划法,时间复杂度为O(n*n),即设置边界条件和更新迭代公式求解最优解。第二种使用二分查找将时间复杂度降为O(nlogn)。本文给出两种方法的实现代码及说明。示例:图1最长递增子序列输入......
  • CF1924D Balanced Subsequences 题解
    先判掉\(k>\min(n,m)\)的情况。首先有个明显的计算最长合法括号子序列的贪心方法:初始一个值为\(0\)的计数器,从左到右枚举每个字符,遇到(时将计数器加一,遇到)时如果计数器不为\(0\)就减一然后将答案加一。考虑绘制它的折线图。初始时纵坐标为\(0\),从左到右枚举每个字符......
  • Link with Monotonic Subsequence(分块,思维)
    First,let'sreviewsomedefinitions.Feelfreetoskipthispartifyouarefamiliarwiththem.Asequence aaaisanincreasing(decreasing)subsequenceofasequence bbbif aaacanbeobtainedfrom bbbbydeletionofseveral(possibly,zeroorall)......
  • CF1922E Increasing Subsequences
    一个显然的思路就是构造很多互不相关的上升序列。但是这样构造出来的\(n\)是\(O(\log_2^2n)\)量级的,所以需要考虑新做法。假设我们本来有一个上升序列,我们能否往里面插数?如果插入的数前面本来有\(x\)个数,那么它有\(2^x\)的贡献。于是容易想到先写一个最大的上升序列,再二......