Codeforces Round 867 (Div. 3) - G1. Magic Triples (Easy Version)

文章描述了一个编程竞赛中的问题,要求在给定的整数数组中找到满足特定关系的三元组(i,j,k)的数量,其中a[j]=b*a[i]且a[k]=a[j]*b。解决方法是通过枚举中间值x,检查其因子b,以O(n*sqrt(mxm))的时间复杂度计算答案。代码中展示了如何利用因子数组和排序优化求解过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Codeforces Round 867 (Div. 3)

G1.Magic Triples (Easy Version)

题意:给定一个整数数组a,要求找出三元组(i,j,k)对应的 a [ i ] a[i] a[i], a [ j ] a[j] a[j], a [ k ] a[k] a[k] 维持 a [ j ] = b ∗ a [ i ] , a [ k ] = a [ j ] ∗ b a[j]=b*a[i],a[k]=a[j]*b a[j]=ba[i],a[k]=a[j]b的关系, 统计成对不同的三元组个数

思路:值域上界有mxm = 1e6,我们可以去枚举中间那个数x(桥梁),所以要去判断 x / b x/b x/b(b是x的因子)和 x ∗ b x*b xb是否存在( b ∗ x < = m x m b*x<= mxm bx<=mxm),考虑枚举 b(由于要保证 b ∗ x < = m x m b*x<=mxm bx<=mxm,所以我们只需要 O ( m x m ) O(\sqrt{mxm}) O(mxm ),也就是b至多到1e3),总的复杂度 O ( n ∗ m x m ) O(n*\sqrt{mxm}) O(nmxm ),足以通过此题,接下来考虑统计答案, 当b=1,也就是三个相同的数时容易得出结果,考虑b不为1,我们可以在 O ( x ) O(\sqrt{x}) O(x )的复杂度内求出一个数的全部因子,然后遍历这些因子,若当前因子 i t ∗ x > m x m it*x>mxm itx>mxm则已经无解,选择遍历x的下个因子it,若存在因子it使得 x / i t x/it x/it x ∗ i t x*it xit同时存在,则将三元对数加入答案

Code:

#include <bits/stdc++.h>
#define int long long
#define rep(i,a,n) for(int i=a; i<=n; i++)
#define ios ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define pb push_back
using namespace std;

const int mxn=2e5+10, mxm=1e6;
int a[mxn];
vector<int> rs(int x){
	vector<int> v;
	for(int i=1; i*i<=x; i++){
		if(x%i==0){
			v.pb(i);
			if(i!=x/i) v.pb(x/i);
		}
	}
	sort(v.begin(),v.end());
	return v;
}
void solve(){
	auto get_same=[&](int x)->int{
		return x*(x-1)*(x-2);
	};
	int n;
	cin>>n;
	map<int,int> Mp;
	rep(i,1,n) cin>>a[i], Mp[a[i]]++;
	int ans=0;
	for(auto &[x,y]:Mp){
		ans+=get_same(y);
		auto v=rs(x);
		for(auto it:v){
			if(it==1) continue;//因子为1已经统计过
			if(it*x>mxm) break;
			if(Mp.count(x/it)&&Mp.count(x*it)){
				ans+=y*Mp[x/it]*Mp[x*it];
			}
		}
	}
	cout<<ans<<'\n';
}
signed main(){
	ios;
	int t=1;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;		
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值