-
- 题意:给出一个长度为n的序列,问存在多少个三元组满足ai x aj = ak (i, j, k可以相同)。(1 <= n <= 1e6, 1 <= ai <= 1e6)
- 题解:若要满足题目条件,那么ai x aj必须要小于或等于序列中最大值或1e6均可,可以用hash表记录每个数值出现的次数,最后枚举i、j来得到k,在枚举的过程中i需要从1~1e6,而j的范围则是i * j <= maxv或1e6,这样时间复杂度可以达到O(n * sqrt(n))。
- ps:这题卡map。哈希表不能用map来存;
- ps:这题通过枚举序列中的数则不好进行处理,因为序列中假如出现很多极小的数,如9e5个1, 1e5个2,那么这时候第二层循环的结束条件若设为a[i] * a[j] <= 1e6也无法进行优化,时间复杂度还是O(n^2)。
- 代码:
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
const int N = 1e6;
int n;
int vis[N + 5];
ll res = 0;
//map<int, int> vis;
int main()
{
int maxv = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
int a;
scanf("%d", &a);
vis[a] ++;
maxv = max(maxv, a);
}
for(int i = 1; i <= N; i++)
{
for(int j = 1; i * j <= maxv; j++)
{
int k = i * j;
res += (ll)vis[i] * (ll)vis[j] * (ll)vis[k];
}
}
printf("%lld\n", res);
return 0;
}