题目:
A sequence of positive integers is called great for a positive integer x, if we can split it into pairs in such a way that in each pair the first number multiplied by x is equal to the second number. More formally, a sequence a of size n is great for a positive integer x, if n is even and there exists a permutation p of size n, such that for each i (1≤i≤n2) ap2i−1⋅x=ap2i.
Sam has a sequence a and a positive integer x. Help him to make the sequence great: find the minimum possible number of positive integers that should be added to the sequence a to make it great for the number x.
Input
Each test contains multiple test cases. The first line contains a single integer t (1≤t≤20000) — the number of test cases. Description of the test cases follows.
The first line of each test case contains two integers n, x (1≤n≤2⋅105, 2≤x≤106).
The next line contains n integers a1,a2,…,an (1≤ai≤109).
It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.
Output
For each test case print a single integer — the minimum number of integers that can be added to the end of a to make it a great sequence for the number x.
Example
inputCopy
4
4 4
1 16 4 4
6 2
1 2 2 2 4 7
5 3
5 2 3 5 15
9 10
10 10 10 20 1 100 200 2000 3
outputCopy
0
2
3
3
Note
In the first test case, Sam got lucky and the sequence is already great for the number 4 because you can divide it into such pairs: (1,4), (4,16). Thus we can add 0 numbers.
In the second test case, you can add numbers 1 and 14 to the sequence, then you can divide all 8 integers into such pairs: (1,2), (1,2), (2,4), (7,14). It is impossible to add less than 2 integers to fix the sequence.
题意:
对于一个正整数序列,将其元素两两分为一对,使得每队中元素 a 乘 x 等于元素 b。
现有一个长度为 n 的正整数序列,为满足上述条件,求至少需要向本序列中添加几个元素。
思路:
数组 a 存初始序列,升序排列数组,遍历数组中的元素,看有多少元素不满足 a[i] * x == a[j]。
由于已配对元素不需要再考虑,故数组我用了动态数组vector,取其erase函数用来删除元素。
代码:
#include <iostream>
#include <cstdio>
#include <string.h>
#include <set>
#include <algorithm>
#include <vector>
typedef long long ll;
using namespace std;
vector<int> v;
bool half_find(int l,int r,int x){//二分查找
int ha;
while(l<r){
ha = (l+r)/2;
if(v[ha]==x){
v.erase(v.begin()+ha);
return true;
}
else if(v[ha]>x)
r = ha;
else
l = ha+1;
}
if(v[l]==x){
v.erase(v.begin()+l);
return true;
}else
return false;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,ans=0,x;
scanf("%d%d",&n,&x);
for(int i=0;i<n;i++){
int a;
scanf("%d",&a);
v.push_back(a);
}
sort(v.begin(),v.end());
vector<int>::iterator it;
for(it = v.begin();it != v.end();it++){
//如果乘积大于序列中最大的数字
//那么剩余的数字都无法配对
ll tem = ll(*it) * ll(x);//不用long long 会溢出
if(tem > v[v.size()-1]){
ans+=v.end()-it;
break;
}
// it - v.begin() 即当前元素在数组中的下标
if(!half_find(it-v.begin(),v.size()-1,*it * x))
ans++;
}
printf("%d\n",ans);
v.clear();
}
return 0;
}