Description |
求求你了求求你了,帮帮可莉吧! 可莉最近在学习除法,你可以帮她解决一下的问题吗 找出整数数列中有多少对i,j使ai/aj=x且ai%aj=0 (i!=j) tips:aj!=0 |
Input |
第一行一个T (1 <= T <= 30) 代表样例个数 每个样例第一行有一个n (1 <= n <= 106), x (0 <= x <= 10) 接下来一行为n个整数ai (0 <= ai <= 106) |
Output |
每个样例输出一行,每行一个整数,代表答案 |
Sample Input |
1 7 2 2 1 2 4 8 2 5 |
Sample Output |
7 |
下面是题目链接:G.可莉学除法 @ Hrbust Online Judge(存在内网访问限制)
分析:第一个思路是将整个数列顺序排列,使用sort函数排列之后,从最后一位开始向前除,之后经过一边循环之后从倒数第二个数字开始继续除以前面的所有数字,但是经过简单的计算之后我们可以知道这个时间复杂度很高,近似是O(n2)数量级的,明显超时。之后想到可以用二分法解决这个问题,于是可以使用lower_bound函数来找出答案,下面是代码。
#include <bits/stdc++.h>
#define endl '\n'
#define buff ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
/*
#pragma GCC optimize ("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC optimize(3)
*/
using namespace std;
typedef long long ll;
typedef pair<ll, ll> pll;
typedef vector<ll> vll;
typedef vector<pair<ll, ll>> vpll;
const ll MAX_INT = 0x3f3f3f3f;
const ll MAX_LL = 0x3f3f3f3f3f3f3f3f;
const ll CF = 2e5 + 9;
const ll mod = 1e9 + 7;
void solve()
{
int n, x;
cin >> n >> x;
vector<int> a(n);
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
sort(a.begin(), a.end());
int ans = 0;
if (x == 0)
{
for (int i = 0; i < n; i++)
{
if (a[i] == 0)
{
ans++;
}
}
cout << ans << endl;
return;
}
for (int i = 0; i < n; i++)
{
if (a[i] % x == 0)
{
int j = lower_bound(a.begin(), a.end(), a[i] / x) - a.begin();
int k = upper_bound(a.begin(), a.end(), a[i] / x) - a.begin();
ans += k - j;
}
}
cout << ans << endl;
}
int main()
{
buff;
int t = 1;
cin >> t;
while (t--)
{
solve();
}
return 0;
}