ABC292 BCD 题解 -lianchanghua

lianchanghua 2023-06-28 22:03:59 7

关注这个人!我从他那抄的

B题

题目传送门

题目大意

个人 个事件。 有三种情况:

  • 输入 ,当 有两次 时,就没了。
  • 输入 ,当 有一次 时,就没了。
  • 输入 ,询问选手 是否还在,不在输出 Yes,否则输出 No

思路分析

其实没什么思路,无脑判断即可

AC Code

#include<bits/stdc++.h>
#define int long long 
using namespace std;
int cnt[105],g[105];
signed main(){
  	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n,q;
	cin>>n>>q;
	while(q--){
		int a,b;
		cin>>a>>b;
		if(a==1){
			cnt[b]++;
			if(cnt[b]>=2)	g[b]=1;
		}
		else if(a==2)	g[b]=1;
		else{
			if(g[b]==1)	cout<<"Yes\n";
			else		cout<<"No\n";
		}
	}
	return 0;
}

C题

题目传送门

题目大意

给定正整数 ,求有序正整数四元组 的个数使得

注:有序指实质相同,但顺序不同的算不同的两个。

思路分析

拆分成两个数后,两个数的因数个数相乘即可

为什么呢?

比如,把 拆成 。那么把 拆成 的形式,一共有 的因数个数种。 也一样。所以把 拆成 时,就有 , 两个数的因数个数相乘种。

AC Code

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,ans;
int solve(int x){
	int s=0;
    for(int i=1;i*i<=x;i++){
        if(x%i==0){
        	s++;
            if(i*i!=x) s++;
        }
    }
    return s;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
    cin>>n; 
    for(int i=1;i<=n;i++)	ans+=solve(i)*solve(n-i);
    cout<<ans;
    return 0;
}

D题

题目传送门

备注:本题本人使用了前不久学的 并查集 芝士,还不会的请勿模仿。

思路分析

用并查集,快速计数当前点所在的连通快的点的个数与边的个数,最后判断即可。(怎么比C题还简单呢)

AC 代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,f[200005],cnt1[200005],cnt2[200005],a[200005],b[200005];
int find(int x){
	if(f[x]!=x)	return f[x]=find(f[x]);
	else		return x;
}
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++)	f[i]=i;
    for(int i=1;i<=m;i++){
        cin>>a[i]>>b[i];
        int r1=find(a[i]);
		int r2=find(b[i]);
		if(r1!=r2)	f[r2]=f[r1];
    }
    for(int i=1;i<=m;++i){
    	int r=find(a[i]);
		cnt1[r]++;
	}
    for(int i=1;i<=n;++i){
    	int r=find(i);
		cnt2[r]++;
	}
    for(int i=1;i<=n;++i){
		if(cnt1[i]!=cnt2[i]){
			cout<<"No";
			exit(0);
		}
	}      
    cout<<"Yes";
    return 0;
}
{{ vote && vote.total.up }}