题目链接

点我跳转

题目大意

给定一个长度为 \(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. python中is,== 和 in 的区别

    python对象的三个基本要素:id(身份标识),type(数据类型)和value(值). is 运算符:判断的是对象间的唯一身份标识(id). == 运算符:判断的是对象间的value(值)是否相同 ...

  2. 6.PowerShell DSC核心概念之LCM

    什么是LCM? 本地配置管理器 (LCM) 是DSC的引擎. LCM 在每个目标节点上运行,负责分析和执行发送到节点的配置. 它还负责 DSC 的许多方面,包括以下各方面. 确定刷新模式(推送或请求) ...

  3. Python_小程序(云开发)

    一.云开发API初始化 wx.cloud.init({ env:'test-x1dzi', //环境ID traceUser:true //是否在控制台查看用户信息 }) 二.云开发API初始化-服务 ...

  4. cookie,session,token之间的联系与区别

    发展史 1.很久很久以前,Web 基本上就是文档的浏览而已, 既然是浏览,作为服务器, 不需要记录谁在某一段时间里都浏览了什么文档,每次请求都是一个新的HTTP协议, 就是请求加响应,  尤其是我不用 ...

  5. Leetcode(145)-二叉树的后序遍历

    给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 思路:一开始编写二叉树后序遍历的程序,感觉定级为困难有点欠妥,确实,如果用 ...

  6. 手工数据结构系列-C语言模拟栈 hdu1022

    这个题我一开始是这么想的.. 爆搜所有可能的出栈序列 然后对输入进行匹配 这样我感觉太慢 然后我们可以想到直接通过入栈序列对出栈序列进行匹配 但是我犯了一个错误..那就是出栈序列一定到入栈序列里找.. ...

  7. Vue Component Registration All In One

    Vue Component Registration All In One Vue 注册自定义组件 <template> <div class="back-to-top-c ...

  8. Flipper & React Native

    Flipper & React Native Flipper Flipper是一款用于调试移动应用程序的出色开发人员工具,在Android和iOS社区中颇受欢迎. Flipper is a g ...

  9. react slot component with args

    react slot component with args how to pass args to react props child component https://codesandbox.i ...

  10. github & code owners

    github & code owners https://help.github.com/en/github/creating-cloning-and-archiving-repositori ...