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 ...
随机推荐
- Educational Codeforces Round 96 (Rated for Div. 2) D. String Deletion (思维)
题意:有一个\(01\)串,每次操作要先删除一个位置上的元素,然后删除相同前缀和,直到字符串被删完,问最多能操作多少次. 题解: 对于一个长度大于\(1\)的相同前缀,我们最多只能对它操作一次,然后就 ...
- (数据科学学习手札106)Python+Dash快速web应用开发——回调交互篇(下)
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...
- Git命令回退代码并同步到远程仓库
git log 找到要回退的commit版本号并复制 git reset --hard [commitid] 本地库版本回退 git push -f origin [branchName] 同步到远端 ...
- Windows环境下Node.js环境搭建
1.Node.js下载与安装 https://nodejs.org/zh-cn/download/ Windows现在windows安装包(.msi),现在后手动安装,安装目录无要求,选项默认即可 2 ...
- K8S(08)交付实战-交付jenkins到k8s集群
k8s交付实战-交付jenkins到k8s集群 目录 k8s交付实战-交付jenkins到k8s集群 1 准备jenkins镜像 1.1 下载官方镜像 1.2 修改官方镜像 1.2.1 创建目录 1. ...
- leetcode 2 两数相加 考虑溢出
先用int存了结果然后出错,int溢出了. 真是憨批嗷. 不用考虑保存结果,直接一位一位计算就行. 感觉被描述误导了. /** * Definition for singly-linked list. ...
- 洛谷p1966 火柴排队 (逆序对变形,目标排序
题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...
- UTM & User Tracking Message
UTM & User Tracking Message utm_source https://marketingplatform.google.com/about/resources/link ...
- npm init & npx create & yarn create
npm init & npx create & yarn create https://create-react-app.dev/docs/getting-started/#creat ...
- Linux安装MySQL_全网最详细
Linux安装MySQL 编辑于2021-02-19 本文中MySQL安装目录为/usr/local/mysql 上传MySQL安装包至/usr/local目录,执行命令解压 [root@JetXi ...