山东省网站建设_网站建设公司_支付系统_seo优化
2026/1/2 13:44:04 网站建设 项目流程

对于本题的数据范围,大家可能难以下手。

我们可以向一件事,在将这 \(N\) 个数的最小公倍数分解质因数后,每个数分解质因数里面的素因子都会出现。那它的次数是这 \(N\) 个数里面相应的素因子的次数的最大值。

我们把一个数变为 \(1\) 对于最小公倍数的影响,如果他这个质因数 \(p_{i,m_i}^{e_i,m_i}\) 他在这 \(N\) 个数的分解质因数中出现或某个质因数跟它底数相同,次数比它大或等于,那么把它删去没有任何影响。否则把它变成 \(1\) 最小公倍数一定会改变。

我们要记每个相同底数次方的最大值和次大值。但是数字太大了,所以我们要用 map 来记可以方便一些。

那为什么要记呢?因为找到相同底数次方的最大值后,把它变成 \(1\)\(\operatorname{LCM}\) 的取值就会多一种。

时间复杂度其实是 \(\mathcal O(\sum m_i \log \sum m_i)\)。用 map 更新最大值和次大值的时间复杂度是 \(\mathcal O( \log \sum m_i)\)。所以上面的时间复杂度要乘个 $ \log \sum m_i$。如果你不想乘 $ \log \sum m_i$,你可以用哈希或其他算法,这里就不用哈希了。

AC记录

#include <bits/stdc++.h>
using namespace std;
struct Node{int p,v;Node(int ps,int vs){p=ps,v=vs;}
};
int n;
vector<Node> a[200001];
map<int,pair<int,int>> c;
int main(){scanf("%d",&n);for(int i=1;i<=n;i++){int m;scanf("%d",&m);for(int j=1;j<=m;j++){int x,y;scanf("%d%d",&x,&y);a[i].push_back(Node(x,y));if(y>c[x].first)c[x].second=c[x].first,c[x].first=y;else if(y>c[x].second)c[x].second=y;}}int ans=0;bool ok=false;for(int i=1;i<=n;i++){bool z=false;for(auto j:a[i])if(j.v==c[j.p].first&&j.v!=c[j.p].second){++ans,z=true;break;}if(!z)ok=true;}if(ok)++ans;printf("%d\n",ans);
}

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询