AtCoder ABC 259 E LCM on Whiteboard
题意:
将任一\(a_i\)换成1后的\(LCM(a_1,a_2...a_n)\)能够产生多少种结果
分析:
我们要知道这个式子的另一种表示,因为题目给出的\(a_i\)是以唯一分解定理的形式给出的,这就提示了我们要往质因数和他的次数上靠。通过LCM的定义,易得\(LCM(a_1, a_2, a_3...)\)的值为所有质因子的次幂最大的乘积。
\[lcm(2^3*3^2,3^5,7^2*5^2)=2^3*3^5*7^2*5^2
\]
实现过程:
所以可以写出代码,当对于一个\(a_i\),如果他存在一个\(p^x\)其x为p的幂次的最大值,且只出现一次,将该数变为1将会产生一个新的结果。
要注意若每个数消去后都产生一个新的结果的话,要去掉原来的\(lcm\),特判一下
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i, a, n) for(int i = a; i < n; i++)
#define all(x) x.begin(), x.end()
#define pb push_back
#define ios ios::sync_with_stdio(false);cin.tie(0);
#define debug(x) cout << x << endl;
#define SZ(x) (int)x.size()
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int inf = 0x3f3f3f3f;
void read(int &x) {int s = 0, f = 1; char ch = getchar(); while(!isdigit(ch)) {f = (ch == '-' ? -1 : f); ch = getchar();} while(isdigit(ch)) {s = s * 10 + ch - '0'; ch = getchar();} x = s * f;}
int n;
vector<PII> g[200005];
signed main()
{
map<int, int> mp;
map<int, int> mp_tot;
int m, p, c;
cin >> n;
rep(i, 0, n) //对于n个数分别读入其质因数和次幂,并保存最大值
{
cin >> m;
while(m --)
{
cin >> p >> c;
g[i].pb({p, c});
if(mp[p] < c)
mp[p] = c, mp_tot[p] = 1;
else if(mp[p] == c) //如重复出现,一定是在a_i,a_j(i!=j中)
mp_tot[p] ++;
}
}
int res = 1, repeat = 1;
for(int i = 0; i < n; i ++)
{
int flag = 0; //如果a_i中不存在最大次幂的数,那么将他变为1不会产生新的答案
for(PII x : g[i]) //寻找a_i内是否存在最大次幂的数
{
p = x.first, c = x.second;
if(mp[p] == c && mp_tot[p] == 1) //a_i出现了合法的最高次幂
flag = 1;
}
res += flag;
if(!flag) repeat = 0; //既然有不会造成影响的情况,就要不需要去重了
}
cout << res - repeat << '\n';
}