首页 > 其他分享 >G. Natlan Exploring

G. Natlan Exploring

时间:2024-11-19 10:39:54浏览次数:1  
标签:Natlan Exploring gcd City int 约数 Output rightarrow

G. Natlan Exploring

You are exploring the stunning region of Natlan! This region consists of $n$ cities, and each city is rated with an attractiveness $a_i$. A directed edge exists from City $i$ to City $j$ if and only if $i < j$ and $\gcd(a_i,a_j)\neq 1$, where $\gcd(x, y)$ denotes the greatest common divisor (GCD) of integers $x$ and $y$.

Starting from City $1$, your task is to determine the total number of distinct paths you can take to reach City $n$, modulo $998\,244\,353$. Two paths are different if and only if the set of cities visited is different.

Input

The first line contains an integer $n$ ($2 \leq n \leq 2 \cdot 10^5$) — the number of cities.

The second line contains $n$ integers $a_1, a_2, \ldots, a_n$ ($2 \leq a_i \leq 10^6$) — the attractiveness of each city.

Output

Output the total number of distinct paths you can take to reach City $n$, modulo $998\,244\,353$.

Examples

Input

5
2 6 3 4 6

Output

5

Input

5
4 196 2662 2197 121

Output

2

Input

7
3 6 8 9 11 12 20

Output

7

Input

2
2 3

Output

0

Note

In the first example, the five paths are the following:

  • City $1\rightarrow$ City $5$
  • City $1\rightarrow$ City $2\rightarrow$ City $5$
  • City $1\rightarrow$ City $2\rightarrow$ City $3\rightarrow$ City $5$
  • City $1\rightarrow$ City $2\rightarrow$ City $4\rightarrow$ City $5$
  • City $1\rightarrow$ City $4\rightarrow$ City $5$

In the second example, the two paths are the following:

  • City $1\rightarrow$ City $3\rightarrow$ City $5$
  • City $1\rightarrow$ City $2\rightarrow$ City $3\rightarrow$ City $5$

 

解题思路

  建图后会发现是一个拓扑图,因此可以 dp。然后就一直想着怎么优化建图结果做不出来。

  事实上可以直接暴力 dp,定义 $f(i)$ 表示从 $1$ 出发到达 $i$ 的不同路径数量,那么转移方程就是 $f(i) = \sum\limits_{j=1}^{i-1}{[\gcd(a_i, a_j) \ne 1]f(j)}$,复杂度是 $O(n^2 \log{n})$。可以知道任意一个数与 $a_i$ 求 $\gcd$ 的结果只会是 $a_i$ 的约数(本题中不考虑 $1$),因此我们可以只从前面含 $a_i$ 约数的 $a_j$ 转移过来。

  具体来说,先用 $g(d)$ 累加前面含约数 $d$ 的 $a_j$ 的 $f(j)$,枚举 $a_i$ 的约数 $d$,有 $f(i) \gets f(i) + g(d)$。很明显这会有重复转移的问题,比如如果 $\gcd(a_i, a_j) = 10$,意味着 $a_j$ 含有约数 $2,5,10$,那么 $f(j)$ 会被累加了 $3$ 次。可以通过容斥避免重复计算,公式如下:$$\sum\limits_{i}{g(d_i)} - \sum\limits_{i<j}{g(d_i \cdot d_j)} + \sum\limits_{i<j<k}{g(d_i \cdot d_j \cdot d_k)} - \sum\limits_{i<j<k<u}{g(d_i \cdot d_j \cdot d_k \cdot d_u)} + \cdots$$

  容斥的复杂度是 $O(2^{d(A)})$,其中 $A = \max\{a_i\}$,$d(A)$ 表示 $A$ 的约数个数,大约是 $\sqrt[3]{A}$ 的数量级。显然还是会超时。

  思考一下,我们有必要枚举所有的约数吗?因为我们只关心 $a_i$ 和 $a_j$ 是否互质,而不关心具体的 $\gcd$ 是什么,因此只需枚举 $a_i$ 的质因子就可以了。这样只要 $\gcd(a_i, a_j) \ne 1$,那么 $a_j$ 必然含 $a_i$ 的某个质因子。由于 $10^6$ 内一个数最多含 $7$ 个不同的质因子,因此容斥的复杂度的数量级是 $O(2^7)$。

  设 $d = p_1 \cdot p_2 \cdots$ 表示单个质数的乘积。 实现时需要维护 $g(d)$ 表示满足 $d \mid a_i$ 对应的 $f(i)$ 的和。

  AC 代码如下,时间复杂度为 $O(n \log{n} + 2^7 n)$:

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

typedef long long LL;

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

int prime[M], minp[M], cnt;
bool vis[M];
int f[N], g[M];

void get_prime(int n) {
    for (int i = 2; i <= n; i++) {
        if (!vis[i]) prime[cnt++] = i, minp[i] = i;
        for (int j = 0; prime[j] * i <= n; j++) {
            vis[prime[j] * i] = true;
            minp[prime[j] * i] = prime[j];
            if (i % prime[j] == 0) break;
        }
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    get_prime(M - 1);
    f[1] = 1;
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        vector<int> fs;
        while (x > 1) {
            int p = minp[x];
            fs.push_back(p);
            while (minp[x] == p) {
                x /= p;
            }
        }
        for (int j = 1; j < 1 << fs.size(); j++) {
            int p = 1, c = 0;
            for (int k = 0; k < fs.size(); k++) {
                if (j >> k & 1) p *= fs[k], c++;
            }
            if (c & 1) f[i] = (f[i] + g[p]) % mod;
            else f[i] = (f[i] - g[p]) % mod;
        }
        for (int j = 1; j < 1 << fs.size(); j++) {
            int p = 1;
            for (int k = 0; k < fs.size(); k++) {
                if (j >> k & 1) p *= fs[k];
            }
            g[p] = (g[p] + f[i]) % mod;
        }
    }
    cout << (f[n] + mod) % mod;
    
    return 0;
}

 

参考资料

  Codeforces Round 988 (Div. 3) Editorial:https://codeforces.com/blog/entry/135533

标签:Natlan,Exploring,gcd,City,int,约数,Output,rightarrow
From: https://www.cnblogs.com/onlyblues/p/18554386

相关文章

  • 【转载】遗传算法—Exploring NEAT-Neuroevolution of Augmenting Topologies
    原文地址:https://hunterheidenreich.com/posts/neuroevolution-of-augmenting-topologies/AWorldofNeuroEvolutionRecently,I’vebeendoingalotofreadingaboutsomethingcalledneuroevolution.Atahigh-level,theideaisverysimple.Insteadofrelyingo......
  • 题解:UVA1362 Exploring Pyramids
    思路:显然的,若不是叶子结点都应该至少遍历两次。于是两个相同访问之间就可能是一颗子树。更加具体的,如同\(s_l,\dots,s_k,\dots,s_r\),使得\(s_l=s_k\),那么就可以认为\(s[l,k]\)是\(s[l,r]\)的一颗子树,设区间\(s[l,r]\)的结构数量为\(f_{l,r}\),那么根据乘法原理,当把\(......
  • 【人脸伪造检测后门攻击】 Exploring Frequency Adversarial Attacks for Face Forger
    一、研究动机​ 现有的后门攻击方法生成的对抗样本容易被识别,只是在空间域增加了扰动。为此,作者提出了一种频率对抗性攻击的方法,在频域中增加了对抗性的扰动DCT,接着利用融合模块对不同频段的能量进行微调,有效的避免了在空间范围攻击的冗余噪声:FGSM,PGD,最终通过逆变换生成对抗样......
  • Exploring Qualcomm IPQ5332 and IPQ5322: The Champions of WiFi 7 Solutions
    AsWiFi7technologyrapidlyadvances,Qualcomm'sIPQ5332andIPQ5322chipshaveemergedaspopularchoicesforusers.Thesetwochipsnotonlyexhibitoutstandingperformancebutalsopossessuniquefeaturestailoredtodifferentnetworkrequirement......
  • Exploring the Nexus of Large Language Models and Legal Systems: A Short Survey
    本文是LLM系列文章,针对《ExploringtheNexusofLargeLanguageModelsandLegalSystems:AShortSurvey》的翻译。探索大型语言模型与法律制度的联系:一个简短的调查摘要1引言2大型语言模型在法律任务中的应用3不同国家和地区的微调大型语言模型4大型语言......
  • Exploring Large Language Models and Hierarchical Frameworks for Classification o
    本文是LLM系列文章,针对《ExploringLargeLanguageModelsandHierarchicalFrameworksforClassificationofLargeUnstructuredLegalDocuments》的翻译。探索大型非结构化法律文件分类的大型语言模型和层次框架摘要1引言2相关工作3方法:分类框架(MESc)4结......
  • Non-stationary Transformers: Exploring the Stationarity in Time Series Forecasti
    文章目录摘要1引言2相关工作2.1时间序列预测的深度模型2.2时间序列预测的平稳化3非平稳变压器3.1序列平稳化3.2去平稳化注意力核心思想数据平稳化自注意力机制中的去平稳化操作具体流程为什么需要去平稳化操作总结为什么最终预测结果还要进行去平稳化调整后的......
  • [ICML2022]Open-Sampling Exploring Out-of-Distribution Data for Re-balancing Long
    引入开集样本训练模型有点像dropout,“破坏”某些模型参数防止尾部类的过拟合Motivation长尾学习中的训练数据集分布不平衡的问题,解决方法之一是重采样。重采样主要对于尾部类重复采用,但这种做法往往会导致尾部类的过拟合。为了缓解过拟合[2](Rethinkingthevalueoflabelsf......
  • [论文笔记] Conversing with Copilot: Exploring Prompt Engineering for Solving CS1
    Abstract:Copilot及其他辅助编程的人工智能模型被广泛使用,这篇文章探索了Copilot在哪些任务上表现不佳,prompt在过程中的作用等几个问题。Introduction:Question1:Copilot在CS1programmingproblems上的表现如何?Question2:当Copilot最初失败后,prompt的修改如何......
  • UVA1362 Exploring Pyramids 题解
    题目传送门前置知识欧拉序|区间DP|乘法原理解法DFS序可近似理解为欧拉序,故考虑区间DP。设\(f_{l,r}\)表示\([l,r]\)对应的二叉树的个数,状态转移方程为\(f_{l,r}=\begin{cases}1&l=r\\[s_{l}=s_{r}]\times\sum\limits_{i=l+2}^{r}[s_{l}=s_{i}]\timesf_{......