Language: C++

#include <iostream>
#include <vector>
#include <map>
#include <cmath>
using namespace std;
typedef long long int LL;

bool same_cube = 1, czy_jest_cube = 0;
int n;
LL pom, wynik;
const int stala = 2155, stala_1 = 100007;
const LL reszta = 1000000000000000007LL, wspolczynnikPoczatkowy = 20000000009LL;
bool zajete[stala], odw[stala_1];

LL hasz[stala_1];
map<LL, int> hasz_uzup;
map<LL, int>::iterator it;

vector<LL> liczby;
vector<LL> liczbyPierwsze;

struct potega {
	LL wys;
	LL co;
};
potega dod;
vector<potega> rozklad[stala_1];
vector<potega> nowyRozklad[stala_1];
vector<int> ileRazy;

vector<int> kolejnosc;

LL pomnoz(LL alfa, LL beta) {
    if(alfa == 1) return beta;
    if(alfa%2 == 0) return (2*pomnoz(alfa/2, beta))%reszta;
    return (beta+2*pomnoz(alfa/2,beta))%reszta;
}

void sprawdzHasz(int nr) {
	LL wyn = 0, wspol = wspolczynnikPoczatkowy;
    odw[nr] = 1;
    for(int j = 0; j < nowyRozklad[nr].size(); j++) {
        wyn += pomnoz(wspol, nowyRozklad[nr][j].co*(3-nowyRozklad[nr][j].wys));
        wyn %= reszta;
        wspol = pomnoz(wspol, wspolczynnikPoczatkowy);
    }
    it = hasz_uzup.find(wyn);
    if(it == hasz_uzup.end()) wynik += ileRazy[nr];
    else {
		odw[ it->second ] = 1;
		wynik += max(ileRazy[nr], ileRazy[ it->second ]);
	}
}

void policzHaszUzupelniajacy(int nr) {
    LL wyn = 0, wspol = wspolczynnikPoczatkowy;
    
    for(int j = 0; j < nowyRozklad[nr].size(); j++) {
        wyn += pomnoz(wspol, nowyRozklad[nr][j].co*nowyRozklad[nr][j].wys);
        wyn %= reszta;
        wspol = pomnoz(wspol, wspolczynnikPoczatkowy);
    }
    hasz_uzup[wyn] = nr;
}

bool rowne(int k1, int k2) {
    if(rozklad[k1].size() != rozklad[k2].size()) return 0;
    for(int j = 0; j < rozklad[k1].size(); j++) {
		if(rozklad[k1][j].co != rozklad[k2][j].co) return 0;
		if(rozklad[k1][j].wys != rozklad[k2][j].wys) return 0;
	}
    
	return 1;
}

bool sort_kolejnosc(int k1, int k2) {
	for(int j = 0; j < min(rozklad[k1].size(), rozklad[k2].size()); j++) {
		if(rozklad[k1][j].co != rozklad[k2][j].co) return rozklad[k1][j].co < rozklad[k2][j].co;
		if(rozklad[k1][j].wys != rozklad[k2][j].wys) return rozklad[k1][j].wys < rozklad[k2][j].wys;
	}
    if(rozklad[k2].size() < rozklad[k1].size()) return 0;
	return 1;
}

void rozloz(int nr) {
	for(int j = 0; j < liczbyPierwsze.size() && liczby[nr] > 1; j++) {
		dod.co = liczbyPierwsze[j];
		dod.wys = 0;
		while(liczby[nr]%dod.co == 0) {
			dod.wys = (dod.wys+1)%3;
			liczby[nr] /= dod.co;
		}
		if(dod.wys > 0) rozklad[nr].push_back(dod);
	}
	
	if(liczby[nr] > 1) {
		LL sq = sqrt(liczby[nr]);
		if(sq*sq == liczby[nr]) {
			dod.co = sq;
			dod.wys = 2;
		} else {
			dod.co = liczby[nr];
			dod.wys = 1;
		}
		rozklad[nr].push_back(dod);
	}
}

void sito() {
	for(int i = 2; i < stala; i++) {
		if(!zajete[i]) {
			liczbyPierwsze.push_back(i);
			for(int j = i*i; j < stala; j += i) zajete[j] = 1;
		}
	}
}

LL znajdz_pierwiastek(LL co) {
	LL a = 1, b = 2155, sr;
	
	while(a != b) {
		sr = (a+b)/2;
		if(sr*sr*sr == co) return sr;
		if(sr*sr*sr > co) {
			b = sr;
		} else a = sr+1;
	}
	return a;
}

bool czy_szescian(LL co) {
	LL gdzie = znajdz_pierwiastek(co);
	if(gdzie*gdzie*gdzie == co) return 1;
	return 0;
}

int main() {
	ios_base::sync_with_stdio(0);
	cin >> n;
	for(int i = 0; i < n; i++) {
		cin >> pom;
		if(czy_szescian(pom)) {
			czy_jest_cube = 1;
		} else {
			same_cube = 0;
			liczby.push_back(pom);
		}
	}
	
	if(same_cube) {
		cout << 1 << "\n";
		return 0;
	}
	if(czy_jest_cube) wynik++;
	
	sito();
	
	for(int i = 0; i < liczby.size(); i++) {
		rozloz(i);
		for(int j = 0; j < rozklad[i].size()/2; j++) {
			swap(rozklad[i][j], rozklad[i][ rozklad[i].size()-1-j ]);
		}
		kolejnosc.push_back(i);
	}
	sort(kolejnosc.begin(), kolejnosc.end(), sort_kolejnosc);
	
	//WYPISZ ROZKLAD
	/*
	for(int i = 0; i < kolejnosc.size(); i++) {
		cout << "i == " << i << endl;
		for(int j = 0; j < rozklad[kolejnosc[i]].size(); j++) {
			cout << "(" << rozklad[kolejnosc[i]][j].co << " -> " << rozklad[kolejnosc[i]][j].wys << " razy); ";
		}
		cout << endl;
	}
	*/
	//KONIEC WYPISYWANIA
	
	for(int i = 0; i < rozklad[ kolejnosc[0] ].size(); i++) nowyRozklad[0].push_back( rozklad[ kolejnosc[0] ][i] );
	ileRazy.push_back(1);
	for(int i = 1; i < kolejnosc.size(); i++) {
		if(rowne(kolejnosc[i], kolejnosc[i-1]) ) {
			ileRazy[ ileRazy.size()-1 ]++;
		} else {
			for(int j = 0; j < rozklad[ kolejnosc[i] ].size(); j++) {
				nowyRozklad[ ileRazy.size() ].push_back( rozklad[ kolejnosc[i] ][j] );
			}
			ileRazy.push_back(1);
		}	
	}
	
	for(int i = 0; i < ileRazy.size(); i++) {
        policzHaszUzupelniajacy(i);
	}
    for(int i = 0; i < ileRazy.size(); i++) {
        if(!odw[i]) {
            sprawdzHasz(i);
        }
    }
	cout << wynik << "\n";
	return 0;
}


Compiler output:
a.cc: In function 'int main()':
a.cc:165:9: error: 'sort' was not declared in this scope; did you mean 'sqrt'?
  165 |         sort(kolejnosc.begin(), kolejnosc.end(), sort_kolejnosc);
      |         ^~~~
      |         sqrt