题目描述
输入描述
输出描述
输入样例1
3
1 1 1
输出样例1
27
输入样例2
5
1 2 4 8 16
输出样例2
15
题目大意:给定一个可拥有重复元素的数组 a,问其中有多少对( i , j , k )可满足 ai * aj = ak(对 i , j , k 大小关系无要求)。
本题由于对 i , j , k 大小关系无要求,因此需要考虑排列组合的方式。在数组中,找某个数的约数是否存在比判断两数之积是否存在更方便一些,因此可遍历判断某数的约数是否在数组中成对出现。
本题对时间复杂度较为严格,需要控制在 nlogn ,因此对于数组中的重复元素需要进行跳步,即记录个数进行相乘。而对于 i,j,k 的特殊性,当该对约数并不相等时,还需要乘 2 对排列组合进行考虑。
参考代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1000010;
ll n,x,a[N];
int main(){
ll _max=0;
cin>>n;
for(ll i=1;i<=n;i++){
cin>>x;
a[x]++;
if(x>_max)
_max=x;
}
ll ans=0;
for(ll i=1;i<=_max;i++)
if(a[i])
for(ll k=1;k*k<=i;k++)
if(i%k==0){
if(k!=i/k)
ans+=2*a[i]*a[k]*a[i/k];
else
ans+=a[i]*a[k]*a[i/k];
}
cout<<ans<<endl;
}