传送门
思路:其一,在这个题中主要学到了multiset这个函数。属于set集合具有自动排序的功能。我们把每个数字分解成它的因子集。如果某个数字的集合数量达到n,那么表明每个数字都有那个因子。
其二,学到了一个数学结论,(a/b)%mod=(a*b^mod-2)%mod;
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 200010;
const ll mod = 1e9+7;
int n,m;
int d;
int a[maxn];
map<int,int> mp[maxn];
multiset<int> s[maxn];
ll qmi(ll a,ll b)
{
ll res = 1;
while(b){
if(b&1) res = res*a%mod;
b>>=1;
a = a*a%mod;
}
return res;
}
ll inv(ll x)
{
return qmi(x,mod-2);
}
void insert(int k,int i,int cnt)
{
if(mp[k].count(i))
{
if(s[i].size() == n) d = d*inv(qmi(i,*s[i].begin()))%mod;
s[i].erase(s[i].find(mp[k][i]));
mp[k][i] = mp[k][i] + cnt;
s[i].insert(mp[k][i]);
if(s[i].size() == n) d = d*qmi(i,*s[i].begin())%mod;
}
else{
mp[k][i] = cnt;
s[i].insert(mp[k][i]);
if(s[i].size() == n) d = d*qmi(i,*s[i].begin())%mod;
}
}
void divide(int k,int x)
{
for(int i = 2;i <= x/i;i++)
if(x%i == 0)
{
int cnt = 0;
while(x%i == 0) cnt++,x /= i;
insert(k,i,cnt);
}
if(x>1) insert(k,x,1);
}
int main()
{
cin >> n >> m;
for(int i = 1;i <= n;i++) cin >> a[i];
d = 1;
for(int i = 1;i <= n;i++) divide(i,a[i]);
while(m--){
int i,x;
cin >> i >> x;
divide(i,x);
cout << d << endl;
}
return 0;
}
反思与总结:问题中涉及的multiset函数作为总动排序的set集合,用处广泛。而且,在找寻因子的时候,divide函数的趣味性和实用性比较强。