Loading

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';
}
posted @ 2022-08-31 15:51  DM11  阅读(38)  评论(0编辑  收藏  举报