题目大意:
给定n 和 p,
规则 :if(x == y * p) 那么x 与 y 互斥。
找出最大的集合,每个元素两两不互斥。
思路:
既然x * p 和 y 互斥,那么,如果有a[i] 满足a[i] * p 和 a[i] 互斥,就删掉a[i] * p。
因为如果删除a[i] * p , 会使a[i] * p * p 可以存在于集合中,所以删a[i] * p 一定不会比删a[i] 差。
给定n 和 p,
规则 :if(x == y * p) 那么x 与 y 互斥。
找出最大的集合,每个元素两两不互斥。
思路:
既然x * p 和 y 互斥,那么,如果有a[i] 满足a[i] * p 和 a[i] 互斥,就删掉a[i] * p。
因为如果删除a[i] * p , 会使a[i] * p * p 可以存在于集合中,所以删a[i] * p 一定不会比删a[i] 差。
因为要保证删除的时候能够删除a[i] * p, 所以把元素从小到大排一遍序。
要保证查找的效率,用哈希进行离散化(当然set也行)。
Code:
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<queue>
#include<stack>
#include<bitset>
#include<set>
#include<map>
#include<cctype>
#include<vector>
#define LL long long
#define mem(f, x) memset(f, x, sizeof(f))
#define See(a) cout << #a << " = " << a << endl;
#define xep(i, e) for(int i = 0; i < (e); ++i)
#define rep(i, s, e) for(int i = (s); i <= (e); ++i)
#define drep(i, s, e) for(int i = (s); i >= (e); --i)
#define debug(a, s, e) rep(_i, s, e) { cout << a[_i] << ' ';} cout << endl;
#define debug2(a, s, e, ss, ee) { rep(i_, s, e) {debug(a[i_], ss, ee);}}
const int MAX = 2e9;
const int MIN = -2e9;
const int PI = acos(-1.0);
const double eps = 1e-8;
using namespace std;
const int N = 1e5 + 5;
struct H
{
LL n;
H *next;
H()
{
n = -1;
next = NULL;
}
H(LL n):n(n)
{
next = NULL;
}
}*h;
int n, p;
LL a[N];
void insert(LL n)
{
int t = n % N;
H *p = h + t;
if(p -> n == -1)
{
p -> n = n;
return ;
}
while(p -> next)
{
p = p -> next;
}
p -> next = new H(n);
}
bool find(LL n)
{
int t = n % N;
H *p = h + t;
while(p)
{
if(p -> n == n)
{
p -> n = -1;
return true;
}
p = p -> next;
}
return false;
}
int main()
{
while(~scanf("%d%d", &n, &p))
{
h = new H[N];
xep(i, n)
{
scanf("%lld", &a[i]);
insert(a[i]);
}
int ans = n;
sort(a, a + n);
xep(i, n)
{
if(find(a[i]))
{
if(find(a[i] * p))
{
ans--;
}
}
}
printf("%d\n", ans);
}
return 0;
}
/*
1 2 3 4 5 6 7 8
2 4 6 8 10 12 14 16
*/