题目链接

点我跳转

题目大意

给定一个长度为 \(N\) 的序列 \(A\)

有 \(Q\) 次操作,每次操作给定两个数 \(i\) , \(X\),使得 \(A[i] = A[i] \times X\)

问每次操作后整个序列的 \(gcd\) 为多少 (对 \(1e9+7\) 取模)

解题思路

显然 \(gcd\) 不满足同余定理 ( \(gcd(4,6) \% 3\) \(!=\) \(gcd(4\%3,6)\%3\) )

而 \(A[i]\) 和 \(X\) 最大值都不超过 \(2e5\) , 所以可考虑质因子分解

首先要知道对于一个数它的质因子个数是 \(log\) 级别的

有个贪心的证明方法

要让一个数的质因子最多,那这个数的质因子就应该尽可能小

那么就让他的质因子为 \(2,3,5,7,11,13,...\)

那么它就等于 \(2 × 3 × 5 × 7 × 11 × 13 ×...\)

当乘到 \(29\) 时,它已经大于 \(6e9\) 了,所以一个数的质因子个数是 \(log\) 级别的

于是可以用 \(map\) 开个二维动态数组 \(f[i][j]\),\(f[i][j]\) 表示 \(a[1]\) 的质因子 \(j\) 的幂次

这样使用的空间最多为 \((N + Q) × log\)

对于一个质数 \(P\) ,它对答案产生贡献的条件是: $A[1] $ ~ \(A[N]\) 的质因子都包含 \(P\)

也就是 \(P\) 作为质因子一共出现了 \(N\) 次,而它的贡献显然是出现过的最小幂次

于是可以对每个质数 \(p\) 开个 \(set\)

当 \(A[i]\) 的质因子包含 \(p\) 时,往 \(set[p]\) 里插入对应的幂次

而当 \(set[p].size() =n\) 时,\(p\) 就会对答案产生 \(p^{set[p].begin() - pre[p]}\) 贡献

其中 \(pre[p]\) 表示上一次 \(p\) 对答案产生的贡献,其初始值为 \(0\)

AC_Code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll pow_mod(ll x,ll n,ll mod)
{
ll res = 1;
while(n)
{
if(n & 1) res = res * x % mod;
x = x * x % mod;
n >>= 1;
}
return res;
} int prime[200010] , minprime[200010]; int euler(int n)
{
int c = 0 , i , j; for(i = 2 ; i <= n ; i ++)
{
if(!minprime[i]) prime[++ c] = i , minprime[i] = i; for(j = 1 ; j <= c && i * prime[j] <= n ; j ++)
{
minprime[i * prime[j]] = prime[j]; if(i % prime[j] == 0) break ;
}
}
return c;
} const ll mod = 1e9 + 7; const int N = 3e5 + 10; int n , q , I , X , a[N] , pre[N]; map<int , int>f[N]; multiset<int>se[N]; signed main()
{
ios::sync_with_stdio(false); cin.tie(0) , cout.tie(0); int sum = euler(200000); ll gcdd = 1; cin >> n >> q; for(int i = 1 ; i <= n ; i ++) cin >> a[i]; for(int i = 1 ; i <= n ; i ++)
{
for(int j = 2 ; j * j <= a[i] ; j ++) if(a[i] % j == 0)
{
int c = 0; while(a[i] % j == 0) a[i] /= j , c ++ ; f[i][j] = c; se[j].insert(c);
} if(a[i] > 1) f[i][a[i]] = 1 , se[a[i]].insert(1);
} for(int i = 1 ; i <= sum ; i ++)
{
int p = prime[i]; if(se[p].size() == n)
{
auto j = *se[p].begin(); gcdd = gcdd * pow_mod(1LL * p , 1LL * j , mod) % mod; pre[p] = j;
}
} while(q --)
{
cin >> I >> X; for(int j = 1 ; prime[j] * prime[j] <= X && j <= sum ; j ++) if(X % prime[j] == 0)
{
int c = 0 , p = prime[j]; while(X % p == 0) X /= p , c ++ ; if(f[I].count(p))
{
auto it = se[p].find(f[I][p]); se[p].erase(it);
} f[I][p] += c; se[p].insert(f[I][p]); if(se[p].size() == n)
{
auto it = *se[p].begin(); gcdd = gcdd * pow_mod(p , it - pre[p] , mod) % mod; pre[p] = it;
}
}
if(X > 1)
{
if(f[I].count(X))
{
auto it = se[X].find(f[I][X]); se[X].erase(it);
} f[I][X] += 1; se[X].insert(f[I][X]); if(se[X].size() == n)
{
auto it = *se[X].begin(); gcdd = gcdd * pow_mod(X , it - pre[X] , mod) % mod; pre[X] = it; }
}
cout << gcdd << '\n';
}
return 0;
}

Codeforces1493D GCD of an Array的更多相关文章

  1. upc组队赛17 Greatest Common Divisor【gcd+最小质因数】

    Greatest Common Divisor 题目链接 题目描述 There is an array of length n, containing only positive numbers. N ...

  2. Swift教程之枚举语法

    import Foundation //MARK:-------枚举语法----------- //不像 C 和 Objective-C 一样.Swift 的枚举成员在被创建时不会被赋予一个默认的整数 ...

  3. 2018CCPC桂林站G Greatest Common Divisor

    题目描述 There is an array of length n, containing only positive numbers.Now you can add all numbers by ...

  4. HDU 4947 GCD Array 容斥原理+树状数组

    GCD Array Time Limit: 11000/5500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total ...

  5. AIM Tech Round (Div. 2) D. Array GCD dp

    D. Array GCD 题目连接: http://codeforces.com/contest/624/problem/D Description You are given array ai of ...

  6. Codeforces 623B Array GCD

    Array GCD 最后的序列里肯定有a[1], a[1]-1, a[1]+1, a[n], a[n]-1, a[n]+1中的一个,枚举质因子, dp去check #include<bits/s ...

  7. 【CodeForces 624D】Array GCD

    题 You are given array ai of length n. You may consecutively apply two operations to this array: remo ...

  8. D. Array GCD

    You are given array ai of length n. You may consecutively apply two operations to this array: remove ...

  9. BZOJ3853 : GCD Array

    1 n d v相当于给$a[x]+=v[\gcd(x,n)=d]$ \[\begin{eqnarray*}&&v[\gcd(x,n)=d]\\&=&v[\gcd(\fr ...

随机推荐

  1. Educational Codeforces Round 96 (Rated for Div. 2) D. String Deletion (思维)

    题意:有一个\(01\)串,每次操作要先删除一个位置上的元素,然后删除相同前缀和,直到字符串被删完,问最多能操作多少次. 题解: 对于一个长度大于\(1\)的相同前缀,我们最多只能对它操作一次,然后就 ...

  2. (数据科学学习手札106)Python+Dash快速web应用开发——回调交互篇(下)

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...

  3. Git命令回退代码并同步到远程仓库

    git log 找到要回退的commit版本号并复制 git reset --hard [commitid] 本地库版本回退 git push -f origin [branchName] 同步到远端 ...

  4. Windows环境下Node.js环境搭建

    1.Node.js下载与安装 https://nodejs.org/zh-cn/download/ Windows现在windows安装包(.msi),现在后手动安装,安装目录无要求,选项默认即可 2 ...

  5. K8S(08)交付实战-交付jenkins到k8s集群

    k8s交付实战-交付jenkins到k8s集群 目录 k8s交付实战-交付jenkins到k8s集群 1 准备jenkins镜像 1.1 下载官方镜像 1.2 修改官方镜像 1.2.1 创建目录 1. ...

  6. leetcode 2 两数相加 考虑溢出

    先用int存了结果然后出错,int溢出了. 真是憨批嗷. 不用考虑保存结果,直接一位一位计算就行. 感觉被描述误导了. /** * Definition for singly-linked list. ...

  7. 洛谷p1966 火柴排队 (逆序对变形,目标排序

    题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...

  8. UTM & User Tracking Message

    UTM & User Tracking Message utm_source https://marketingplatform.google.com/about/resources/link ...

  9. npm init & npx create & yarn create

    npm init & npx create & yarn create https://create-react-app.dev/docs/getting-started/#creat ...

  10. Linux安装MySQL_全网最详细

    Linux安装MySQL 编辑于2021-02-19 本文中MySQL安装目录为/usr/local/mysql 上传MySQL安装包至/usr/local目录,执行命令解压 [root@JetXi ...