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 ...
随机推荐
- 【转】Redis数据备份和重启恢复
一.对Redis持久化的探讨与理解 目前Redis持久化的方式有两种: RDB 和 AOF 首先,我们应该明确持久化的数据有什么用,答案是用于重启后的数据恢复.Redis是一个内存数据库,无论是RDB ...
- 一篇文章图文并茂地带你轻松学完 JavaScript 闭包
JavaScript 闭包 为了更好地理解 JavaScript 闭包,笔者将先从 JavaScript 执行上下文以及 JavaScript 作用域开始写起,如果读者对这方面已经了解了,可以直接跳过 ...
- C++实现二叉树的基本操作:建立、遍历、计算深度、节点数、叶子数等
题意: 代码实现: #include<iostream> #include<queue> #include<stack> using namespace std; ...
- [备忘] DevOps 工具上的准备清单(不断补充中……)
目录 概念 发展历程 工具清单 规划 概念 从字面上来看,"DevOps"一词是由英文 Development(开发)和 Operations (运维)组合而成,但它所代表的理念和 ...
- HDU - 4722 Good Numbers 【找规律 or 数位dp模板】
If we sum up every digit of a number and the result can be exactly divided by 10, we say this number ...
- 334A Candy Bags
A. Candy Bags time limit per test 1 second memory limit per test 256 megabytes input standard input ...
- Leetcode(877)-石子游戏
亚历克斯和李用几堆石子在做游戏.偶数堆石子排成一行,每堆都有正整数颗石子 piles[i] . 游戏以谁手中的石子最多来决出胜负.石子的总数是奇数,所以没有平局. 亚历克斯和李轮流进行,亚历克斯先开始 ...
- ARM汇编---程序获取符号的物理地址
在移植u-boot的过程看到过u-boot在重定向时的实现,当时不知道怎么就觉得很好理解就把这个知识点没怎么深入的理解,最近在看华为的鸿蒙OS在Cortex-A平台上的实现过程时再次遇到一时间看不太懂 ...
- golang1.16新特性速览
今天是假期最后一天,明天起大家也要陆续复工了.golang1.16也在今天正式发布了. 原定计划是2月1号年前发布的,不过迟到也是golang的老传统了,正好也趁着最后的假期快速预览一下golang1 ...
- SCSS variable for loop All In One
SCSS variable for loop All In One @each $r: red; $g: green; $b: blue; $colors: ( 1: $r, 2: $g, 3: $b ...