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 ...
随机推荐
- Codeforces Round #653 (Div. 3) E1. Reading Books (easy version) (贪心,模拟)
题意:有\(n\)本书,A和B都至少要从喜欢的书里面读\(k\)本书,如果一本书两人都喜欢的话,那么他们就可以一起读来节省时间,问最少多长时间两人都能够读完\(k\)本书. 题解:我们可以分\(3\) ...
- HTTP的传输编码(Transfer-Encoding:chunked) / net::ERR_INVALID_CHUNKED_ENCODING
https://blog.csdn.net/m0_37668842/article/details/89138733 https://www.cnblogs.com/jamesvoid/p/11297 ...
- 快速获取 Wi-Fi 密码——GitHub 热点速览 v.21.06
作者:HelloGitHub-小鱼干 还有 2 天开启春节七天宅家生活,GitHub 也凑了一把春节热闹,wifi-password 连续霸榜 3 天,作为一个能快速让你连上 Wi-Fi 的小工具,春 ...
- oranges-给mini os 添加内存管理,进程多级反馈队列,进程内存完整性度量
参考: 内存管理: https://www.jianshu.com/p/49cbaccd38c5 crc校验 https://www.cnblogs.com/zzdbullet/p/9580502.h ...
- 关于HashMap遍历,为什么要用entry
Map.entrySet() 这个方法返回的是一个Set<Map.Entry<K,V>>,Map.Entry 是Map中的一个接口,他的用途是表示一个映射项(里面有Key和Va ...
- 操作系统 part3
1.操作系统四特性 并发:一个时间段,多个进程在宏观上同时运行 共享:系统中的资源可以被多个并发进程共同使用(互斥共享,同时共享) 虚拟:利用多道程序设计,利用时分复用(分时系统)和空分复用(虚拟内存 ...
- Mybatis基础:Mybatis映射配置文件,Mybatis核心配置文件,Mybatis传统方式开发
一.Mybatis快速入门 1.1 框架介绍 框架是一款半成品软件,我们可以基于这个半成品软件继续开发,来完成我们个性化的需求! 框架:大工具,我们利用工具,可以快速开发项目 (mybatis也是一个 ...
- 十大排序算法时间复杂度 All In One
十大排序算法时间复杂度 All In One 排序算法时间复杂度 排序算法对比 Big O O(n) O(n*log(n)) O(n^2) 冒泡排序 选择排序 插入排序 快速排序 归并排序 基数排序 ...
- React.createClass vs. ES6 Class Components
1 1 1 https://www.fullstackreact.com/articles/react-create-class-vs-es6-class-components/ React.crea ...
- KMP 算法 & 字符串查找算法
KMP算法 Knuth–Morris–Pratt algorithm 克努斯-莫里斯-普拉特 算法 algorithm kmp_search: input: an array of character ...