Codeforces1493D GCD of an Array
题目链接
题目大意
给定一个长度为 \(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的更多相关文章
- upc组队赛17 Greatest Common Divisor【gcd+最小质因数】
Greatest Common Divisor 题目链接 题目描述 There is an array of length n, containing only positive numbers. N ...
- Swift教程之枚举语法
import Foundation //MARK:-------枚举语法----------- //不像 C 和 Objective-C 一样.Swift 的枚举成员在被创建时不会被赋予一个默认的整数 ...
- 2018CCPC桂林站G Greatest Common Divisor
题目描述 There is an array of length n, containing only positive numbers.Now you can add all numbers by ...
- HDU 4947 GCD Array 容斥原理+树状数组
GCD Array Time Limit: 11000/5500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total ...
- 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 ...
- 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 ...
- 【CodeForces 624D】Array GCD
题 You are given array ai of length n. You may consecutively apply two operations to this array: remo ...
- D. Array GCD
You are given array ai of length n. You may consecutively apply two operations to this array: remove ...
- BZOJ3853 : GCD Array
1 n d v相当于给$a[x]+=v[\gcd(x,n)=d]$ \[\begin{eqnarray*}&&v[\gcd(x,n)=d]\\&=&v[\gcd(\fr ...
随机推荐
- hdu4770 Lights Against Dudely
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...
- hdu5360 Hiking
Problem Description There are n soda conveniently labeled by 1,2,-,n. beta, their best friends, want ...
- 加密算法——RSA算法(c++简单实现)
RSA算法原理转自:https://www.cnblogs.com/idreamo/p/9411265.html C++代码实现部分为本文新加 RSA算法简介 RSA是最流行的非对称加密算法之一.也被 ...
- K8S(01)二进制部署实践-1.15.5
系列文章说明 本系列文章,可以基本算是 老男孩2019年王硕的K8S周末班课程 笔记,根据视频来看本笔记最好,否则有些地方会看不明白 需要视频可以联系我 目录 系列文章说明 1 部署架构 1.1 架构 ...
- SQL优化汇总
今天面某家公司,然后问我SQL优化,感觉有点忘了,今天特此总结一下: 总结得是分两方面:索引优化和查询优化: 一. 索引优化: 1. 独立的列 在进行查询时,索引列不能是表达式的一部分,也不能是函数的 ...
- Leetcode(3)-无重复字符的最长子串
给定一个字符串,找出不含有重复字符的最长子串的长度. 示例: 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3. 给定 &q ...
- VSCode VUE常用配置
{ // vscode默认启用了根据文件类型自动设置tabsize的选项 "editor.detectIndentation": false, // 重新设定tabsi ...
- JSON简单理解
JSON 与 JS 对象的关系 很多人搞不清楚 JSON 和 Js 对象的关系,甚至连谁是谁都不清楚.其实,可以这么理解: JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息 ...
- java8按照lamda表达式去重一个list,根据list中的一个元素
/** * 按照指定字段给list去重 * @param list * @return */ public static List<DataModel> niqueList(List< ...
- POJ 3581 Sequence(后缀数组)题解
题意: 已知某字符串\(str\)满足\(str_1 > max\{str_2,str_3 \cdots str_n\}\),现要求把这个字符串分成连续的三组,然后每组都翻转,问字典序最小是什么 ...