题目链接

点我跳转

题目大意

给定一个长度为 \(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. hdu4770 Lights Against Dudely

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

  2. hdu5360 Hiking

    Problem Description There are n soda conveniently labeled by 1,2,-,n. beta, their best friends, want ...

  3. 加密算法——RSA算法(c++简单实现)

    RSA算法原理转自:https://www.cnblogs.com/idreamo/p/9411265.html C++代码实现部分为本文新加 RSA算法简介 RSA是最流行的非对称加密算法之一.也被 ...

  4. K8S(01)二进制部署实践-1.15.5

    系列文章说明 本系列文章,可以基本算是 老男孩2019年王硕的K8S周末班课程 笔记,根据视频来看本笔记最好,否则有些地方会看不明白 需要视频可以联系我 目录 系列文章说明 1 部署架构 1.1 架构 ...

  5. SQL优化汇总

    今天面某家公司,然后问我SQL优化,感觉有点忘了,今天特此总结一下: 总结得是分两方面:索引优化和查询优化: 一. 索引优化: 1. 独立的列 在进行查询时,索引列不能是表达式的一部分,也不能是函数的 ...

  6. Leetcode(3)-无重复字符的最长子串

    给定一个字符串,找出不含有重复字符的最长子串的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. 给定 &q ...

  7. VSCode VUE常用配置

    {   // vscode默认启用了根据文件类型自动设置tabsize的选项   "editor.detectIndentation": false,   // 重新设定tabsi ...

  8. JSON简单理解

    JSON 与 JS 对象的关系 很多人搞不清楚 JSON 和 Js 对象的关系,甚至连谁是谁都不清楚.其实,可以这么理解: JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息 ...

  9. java8按照lamda表达式去重一个list,根据list中的一个元素

    /** * 按照指定字段给list去重 * @param list * @return */ public static List<DataModel> niqueList(List< ...

  10. POJ 3581 Sequence(后缀数组)题解

    题意: 已知某字符串\(str\)满足\(str_1 > max\{str_2,str_3 \cdots str_n\}\),现要求把这个字符串分成连续的三组,然后每组都翻转,问字典序最小是什么 ...