首页 > 其他分享 >ABC349F题解

ABC349F题解

时间:2024-04-19 20:55:52浏览次数:26  
标签:prime tmp 因数分解 int 题解 MAXN ABC349F 998244353

思想

看到 LCM 想到质因数分解。

首先,我们先把 \(M\) 质因数分解了,根号复杂度刚好 1e8 级别。

然后我们发现一个很显然的性质:如果一个数不是 \(M\) 的因数那他肯定没用。

所以此处我们就把不是因数地踢掉。

我们惊奇地发现因为 \(M\) 的质因数分解最多 \(13\) 个不同的质数,然后我们就可以枚举这些因数直接判断每个数是不是他的倍数,这样就在 \(N \log M\) 的时间内做完了所有数的质因数分解。

此时,全部质因数的个数最多 \(13\)。

那我们直接状压,

我们从左到右枚举这个序列,遇到每个数就把对应质因数分解的状压的数组加一,每次再遍历整个集合,暴力更新。

这样搞的话复杂度是 \(N \times 2^{13}\),看起来会爆,但 2e5*8e3=1.6e9,2s时限,加上取模卡卡常,AT 评测机这么强悍,好像都能过。

代码

// Coded by LightningCreeper.

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

#define int long long

constexpr int MAXN = 2e5 + 5;

int n, m, tmp, a[MAXN], t[MAXN], f[MAXN];
bool flag[MAXN];

vector<int> prime;

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> n >> m;

    tmp = m;

    prime.clear();
    for (int x = 2; x * x <= tmp; x++) {
        int now = 1;
        while (tmp % x == 0) {
            tmp /= x;
            now *= x;
        }
        if (now == 1)
            continue;
        prime.push_back(now);
    }
    if (tmp > 1)
        prime.push_back(tmp);

    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        if (m % a[i] != 0)
            flag[i] = true;
        else
            for (int j = 0; j < prime.size(); j++)
                if (a[i] % prime[j] == 0)
                    t[i] |= 1ll << j;
    }

    for (int i = 1; i <= n; i++) {
        if (flag[i])
            continue;
        for (int j = (1ll << prime.size()) - 1; j >= 0; j--) {
            f[j | t[i]] += f[j];
            if (f[j | t[i]] >= 998244353)
                f[j | t[i]] -= 998244353;
        }
        f[t[i]]++;
        f[t[i]] = (f[t[i]] == 998244353 ? 0 : f[t[i]]);
    }
    cout << f[(1ll << prime.size()) - 1] << endl;

    return 0;
}

// Everyone cannot copy this code to judge.

标签:prime,tmp,因数分解,int,题解,MAXN,ABC349F,998244353
From: https://www.cnblogs.com/LightningCreeper/p/18146763

相关文章

  • 题解 LGP5397【[Ynoi2018] 天降之物】/ 第四分块
    题解P5397【[Ynoi2018]天降之物】/第四分块题目描述一个长为\(n\)的序列\(a\)。你需要实现\(m\)个操作,操作有两种:把序列中所有值为\(x\)的数的值变成\(y\)。找出一个位置\(i\)满足\(a_i=x\),找出一个位置\(j\)满足\(a_j=y\),使得\(|i-j|\)最小,并输出\(|i-......
  • vsCode无法连接服务器问题解决及思考
    背景早上刚打开电脑,准备开始一天的工作。但是发现VSCode无法连接上我的虚拟机了,导致无法工作了,这让我十分头疼。最终花了将近一天的时间将问题解决,但是其中的过程走了不少弯路,浪费了不少时间,也进行了反思。我们作为开发人员,应该要用软件思维去理解这款产品,帮助我们去思考问题。......
  • P4168 [Violet] 蒲公英(题解)
    题目题目描述输入格式输出格式数据范围![]样例输入:63123212153615输出:121思路暴力本题求区间内的最小众数,容易想到去用数组sum[i]表示第i种花的个数,在去便利比较,但是复杂度nm一定会T,这时候就要对暴力进行优化。分块优化1如果我们将所......
  • Codeforces Round 932 (Div. 2)题解(c、d)
    CodeforcesRound932(Div.2)C.MessengerinMAC题目大意给定一些\(a_i\)\(和b_i\),选出尽量多的\(a_i和b_i\),使得\(\sum_{i=1}^ka_{p_i}+\sum_{i=1}^{k-1}\left|b_{p_i}-b_{p_{i+1}}\right|\)小于给定的\(l\)。题目解析由于题目没有要求\(\{p\}\)是升序排列的序列,因此......
  • P6018 [Ynoi2010] Fusion tree 题解
    题目链接:Fusiontree大部分人貌似用的边权01Trie,实际这题用点权01Trie类似文艺平衡树去写更方便。考虑两种常见的区间维护:线段树。使用的是父节点信息是归并了左右区间的信息,适用于不需要考虑父节点的贡献的信息。文艺平衡树。每个点就是一个信息,归并左右子树,外加当......
  • kafka消息只能在一台服务器消费的问题解决过程
    场景:kafka消费端应用部署在两台机器上,其中一台能消费到生产端发出的kafka消息,另一台服务器接收不到任何消息。解决过程:一、从消费端启动日志中找出所有消费端线程2024-04-2320:04:44,726[xx_xxapp03-1556011171628-976bc2af_watcher_executor]INFOkafka.consumer.RangeA......
  • PKUSC2019 D1T1 题解
    前言五一网课的例题,但是网上没有详细的题解(其实就是都没放代码),所以来写一篇。题目可以在这里提交。题目简述有\(n\)(\(n\leq5\times10^5\))个村庄排成一排,每个村庄里有一个人。第\(i\)个村庄里的人要去第\(p_i\)个村庄,且\(p\)是\(1\simn\)的一个排列。他们出行......
  • [题解]ABC282E Choose Two and Eat One
    ABC282EChooseTwoandEatOne又一个图论的回顾——Kruskal最小(最大)生成树算法。看到\(n\)的范围只有\(500\),应该没有什么特别的算法。那么我们考虑建一个*\(n\)个顶点的完全图,节点\(x\)到节点\(y\)的边权值就是\(x^y+y^x\)。然后跑一遍最大生成树,得到的和就是最大结果了。如......
  • RuntimeError: No CUDA GPUs are available问题解决
    RuntimeError:NoCUDAGPUsareavailable问题解决检查GPU是否可用importtorchiftorch.cuda.is_available():print("GPU可用")else:print("GPU不可用")显示当前可用的GPU数量importtorchprint("当前可用的GPU数量:",torch.cuda.device_count())P......
  • [题解]CF33C Wonderful Randomized Sum
    CF33CWonderfulRandomizedSum我们可以发现,如果两区间不交叉也不会影响到结果,所以我们只需要考虑不交叉的情况即可。我们所选择的前缀\(1\simi\)应满足区间和最小,后缀也一样。所以用两个数组\(lr,rl\)分别记录下\(1\simi\)(前缀)最小和、\(i\simn\)(后缀)最小和。然后枚举分割......