Challenge: Nice Clique
Subdomeniu: Number Theory (number-theory)
Scor cont: 100.0 / 100
Submission status: Accepted
Submission score: 1.0
Submission ID: 464735691
Limbaj: cpp14
Link challenge: https://www.hackerrank.com/challenges/niceclique/problem
Cerinta
Given a sequence of $n$ numbers, $D = (d_1, d_2, \dots, d_n)$, what's the maximum size of a subsequence of $D$ in which every pair is a *nice pair*?
The pair $(a, b)$ is a nice pair iff at least one of the following condition holds.
1. The [parity](http://en.wikipedia.org/wiki/Parity_(mathematics)) of the number of distinct prime divisors of $a$ is equal to that of $b$. For example, $18$ has two distinct prime divisors: $2$ and $3$.
2. The parity of the sum of all positive divisors of $a$ is equal to that of $b$.
Input Format
The first line contains a single integer $n$. The second line contains $n$ space-separated integers $d_1, d_2, \dots, d_n$.
Output Format
Print the maximum size of any subsequence of $D$ in which every pair is a nice pair.
Constraints
- $1 \le n \le 200$
- $1 \le d_i \le 10^{15}$
Cod sursa
// https://www.hackerrank.com/challenges/niceClique
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <vector>
using namespace std;
#define MAXP 40000000
#define MAXD 1000000000000000l
#define MAXN 200
bool isPrime[MAXP], ppd[MAXN], psd[MAXN];
int primes[MAXP], nPrimes;
long long modMult(long long a, long long b, long long c) {
long long x = 0, y = a % c;
for ( ; b > 0; y = (y * 2) % c, b >>= 1)
if (b & 1)
x = (x + y) % c;
return x % c;
}
long long modPow(long long a, long long b, long long c) {
long long x = 1, y = a;
for ( ; b > 0; y = modMult(y, y, c), b >>= 1)
if (b & 1)
x = modMult(x, y, c);
return x % c;
}
bool isProbablePrime(long long p, int iteration = 20) {
if (p < 2) return false;
if (p != 2 && p % 2 == 0) return false;
long long a, temp, mod, s = p - 1;
while ((s & 1) == 0)
s >>= 1;
while (iteration--) {
a = rand() % (p - 1) + 1, temp = s;
for (mod = modPow(a, temp, p); temp != p - 1 && mod != 1 && mod != p - 1; temp <<= 1)
mod = modMult(mod, mod, p);
if (mod != p - 1 && temp % 2 == 0) return false;
}
return true;
}
void calcPrimes() {
memset(isPrime, true, sizeof(isPrime));
isPrime[1] = false;
int l = (int) sqrt(MAXD);
for (int i = 2; i <= (int) sqrt(l); i++) {
if (isPrime[i]) {
for (int j = i + i; j <= l; j += i)
isPrime[j] = false;
}
}
nPrimes = 0;
for (int i = 1; i <= l; i++) {
if (isPrime[i])
primes[nPrimes++] = i;
}
}
void calcParities(int i, long long n) {
while (n > 1) {
if ((n > primes[nPrimes - 1] && isProbablePrime(n)) ||
(n <= primes[nPrimes - 1] && isPrime[n])) {
ppd[i] ^= 1;
if (n > 2)
psd[i] = 0;
n /= n;
}
int l = (int) sqrt(n);
for (int j = 0; j < nPrimes && primes[j] <= l; j++) {
if (n % primes[j] == 0) {
int pp = psd[i];
while (n % primes[j] == 0) {
if (primes[j] > 2 && (pp % 2))
psd[i] ^= 1;
n /= primes[j];
}
ppd[i] ^= 1;
break;
}
}
}
}
int getMaximumSubsetSize(vector<long long> ds) {
calcPrimes();
memset(ppd, 0, sizeof(ppd));
memset(psd, 1, sizeof(psd));
int N = ds.size();
for (int i = 0; i < N; i++)
calcParities(i, ds[i]);
int ppd0 = 0;
int ppd1 = 0;
int psd0 = 0;
int psd1 = 0;
for (int i = 0; i < N; i++) {
if (ppd[i]) ppd1++;
else ppd0++;
if (psd[i]) psd1++;
else psd0++;
}
return max(ppd0, max(ppd1, max(psd0, psd1)));
}
int main() {
int n;
long long d;
vector<long long> ds;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> d;
ds.push_back(d);
}
cout << getMaximumSubsetSize(ds) << endl;
return 0;
}
HackerRank Number Theory – Nice Clique
