题目链接

点我跳转

题目大意

给定一个长度为 \(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. 洛谷P1119-灾后重建-floyd算法

    洛谷P1119-灾后重建 题目描述 给出\(B\)地区的村庄数NN,村庄编号从\(0\)到\(N-1\),和所有\(M\)条公路的长度,公路是双向的. 给出第\(i\)个村庄重建完成的时间\(t_i\ ...

  2. Hexo-使用阿里iconfont图标

    Hexo-使用阿里iconfont图标 因为使用hexo搭建的博客中,大家并不懂都有什么图标,fa fa-xx就懵了,不知道都有什么. 首先,fa fa-xxx中的图标可以在 图标库 中寻找. (上面 ...

  3. 洛谷p1886滑动窗口最大最小值 双单调队列

    #include <iostream> #include <cstdio> using namespace std; int n,k,a[1000007],q1[2000007 ...

  4. Redis 集合统计(HyperLogLog)

    统计功能是一类极为常见的需求,比如下面这个场景: 为了决定某个功能是否在下个迭代版本中保留,产品会要求统计页面在上新前后的 UV 作为决策依据. 简单来说就是统计一天内,某个页面的访问用户量,如果相同 ...

  5. keras自定义网络层

    在深度学习领域,Keras是一个高度封装的库并被广泛应用,可以通过调用其内置网络模块(各种网络层)实现针对性的模型结构:当所需要的网络层功能不被包含时,则需要通过自定义网络层或模型实现. 如何在ker ...

  6. surge & free online docs website service

    surge & free online docs website service surge 自定义域的域名 https://surge.sh/help/adding-a-custom-dom ...

  7. 如何实现 React 模块动态导入

    如何实现 React 模块动态导入 React 模块动态导入 代码分割 webpack & code splitting https://reactjs.org/docs/code-split ...

  8. 最新 Apple iPhone 12 价格 All In One

    最新 Apple iPhone 12 价格 All In One 美版价格 Apple iPhone 12 mini $699 Apple iPhone 12 $799 Apple iPhone 12 ...

  9. npm & cli & cp: no such file or directory

    npm & cli & cp: no such file or directory empty files bug https://npm.runkit.com/hui-cli htt ...

  10. 为什么ElasticSearch比MySQL更适合全文索引

    熟悉 MySQL 的同学一定都知道,MySQL 对于复杂条件查询的支持并不好.MySQL 最多使用一个条件涉及的索引来过滤,然后剩余的条件只能在遍历行过程中进行内存过滤,对这个过程不了解的同学可以先行 ...