Description
A k-multiple free set is a set of integers where there is no pair of integers where one is equal to another integer multiplied by k. That is, there are no two integers x and y(x < y) from the set, such that y = x·k.
You're given a set of n distinct positive integers. Your task is to find the size of it's largest k-multiple free subset.
Input
The first line of the input contains two integers n and k (1 ≤ n ≤ 105, 1 ≤ k ≤ 109). The next line contains a list of n distinct positive integers a1, a2, ..., an(1 ≤ ai ≤ 109).
All the numbers in the lines are separated by single spaces.
Output
On the only line of the output print the size of the largest k-multiple free subset of {a1, a2, ..., an}.
Sample Input
6 2 2 3 6 5 4 10
3
Hint
In the sample input one of the possible maximum 2-multiple free subsets is {4, 5, 6}.
题意:是给你一堆数,每个数只出现了一次,以及一个正整数倍数k,定义一种子集里面的x<y且x*k!=y,这种子集元素最多的
时候个数有多大。
看到这道题时,想了好长时间没什么思路,不知道该对谁进行二分查找,看了一下别人的思路,豁然开朗。
思路:先对这些数进行排序,然后找出每一个数的k被在不在这些数里面,如果在,将那个数的位置记录下来,然后就从头开始扫描,遇到一个数,如果没有访问过,就访问它,看看的k倍,k*k倍,k*k*k倍···存不存在,并记录下最终从这个数按照访问它的这些倍数的个数,同时没访问完一个数,标记它已经被访问完,下次就不需要被访问了。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
__int64 n,k,p,i,j,ans,a[100010];
bool b[100010];
int main()
{
while(scanf("%I64d%I64d",&n,&k)!=EOF)
{
for(i=0;i<n;i++)
scanf("%I64d",&a[i]);
sort(a,a+n);
ans=n;
memset(b,false,sizeof(b));
for(i=0;i<n;i++)
{
if(!b[i])
{
p=a[i]*k;
if(p>a[n-1])
continue;
__int64 l=i+1;
__int64 r=n-1;
while(l<=r)
{
__int64 mid=(l+r)/2;
if(a[mid]<p)
{
l=mid+1;
}
else if(a[mid]>p)
{
r=mid-1;
}
else
{
b[mid]=true;
ans--;
break;
}
}
}
}
printf("%I64d\n",ans);
}
return 0;
}