D - Friends
题意:
有n个人,给定m个点对<a,b>,表示a和b是朋友,
如果<a,b>且<b,c>那么<a,c>,即关系举有传递性,
保证m对关系没有自环,但是可能有重边。
现在你要将这n个人分成若干个团体,
要求每个团体里的人两两不是朋友关系。
问最少分成多少个团体。
数据范围:n,m<=2e5
解法:
仔细想了想,因为朋友关系具有传递性,
那么并查集合并之后,每个集合内部就是完全图,
假设集合内有n个人,要将他们拆开,那么要分成n堆.
那么并查集维护一下集合人数,对所有集合的人数取max就是答案.
code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxm=1e6+5;
int pre[maxm];
int num[maxm];
int n,m;
int ffind(int x){
return pre[x]==x?x:pre[x]=ffind(pre[x]);
}
signed main(){
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i=1;i<=n;i++){
pre[i]=i;
num[i]=1;
}
for(int i=1;i<=m;i++){
int a,b;cin>>a>>b;
int x=ffind(a);
int y=ffind(b);
if(x==y)continue;
pre[x]=y;
num[y]+=num[x];
}
int ans=0;
for(int i=1;i<=n;i++){
if(pre[i]==i){
ans=max(ans,num[i]);
}
}
cout<<ans<<endl;
return 0;
}
E - Coprime
题意:
1.称序列a"pairwise coprime",当且仅当a中的数两两互质。
2.称序列a"setwise coprime",
当且仅当a不为"pairwise coprime",但是整个序列的gcd为1。
3.其他情况为"not coprime".
给定长度为n的序列a,要求判断该序列是上面哪种情况.
数据范围:n<=1e6,a(i)<=1e6
解法:
如果不是情况1,那么一定存在两个数,他们有公共质因子,
那么统计每个数质因子出现的情况,如果存在质因子出现两个以上,
那么就不是情况1,否则一定是情况1.
找质因子直接用根号暴力就行.
情况2直接gcd一遍看看是否为1即可.
如果不是情况1和2那就是3咯.
code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxm=1e6+5;
int a[maxm];
int n;
signed main(){
ios::sync_with_stdio(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
map<int,int>mark;
for(int i=1;i<=n;i++){
int x=a[i];
for(int j=2;j*j<=x;j++){
if(x%j==0){
mark[j]++;
while(x%j==0)x/=j;
}
}
if(x!=1){
mark[x]++;
}
}
int ok=1;
for(auto i:mark){
if(i.second>=2){
ok=0;break;
}
}
if(ok){
cout<<"pairwise coprime"<<endl;
return 0;
}
int g=0;
for(int i=1;i<=n;i++){
g=__gcd(g,a[i]);
}
if(g==1){
cout<<"setwise coprime"<<endl;
}else{
cout<<"not coprime"<<endl;
}
return 0;
}