牛客多校2021(七)H. xay loves count(巧妙枚举、思维)

  • 题目:xay loves count

  • 题意:给出一个长度为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))。
    1. ps:这题卡map。哈希表不能用map来存;
    2. 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;
}

posted @ 2021-08-08 10:59  ~K2MnO4  阅读(642)  评论(0)    收藏  举报