結果
| 問題 |
No.3236 累乗数大好きbot
|
| コンテスト | |
| ユーザー |
こめだわら
|
| 提出日時 | 2025-08-15 21:53:09 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 9,480 bytes |
| コンパイル時間 | 3,604 ms |
| コンパイル使用メモリ | 300,188 KB |
| 実行使用メモリ | 7,716 KB |
| 最終ジャッジ日時 | 2025-08-15 21:57:01 |
| 合計ジャッジ時間 | 67,253 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 30 TLE * 1 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
#define rep(i,n) for(ll i=0;i<n;++i)
#define all(a) (a).begin(),(a).end()
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
template<class T> T div_floor(T a, T b) { return a / b - ((a ^ b) < 0 && a % b); }
template<class T> T div_ceil(T a, T b) { return a / b + ((a ^ b) > 0 && a % b); }
template <typename T, typename U> inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; }
template <typename T, typename U> inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; }
namespace noya2{
namespace fast_factorize {
/*
See : https://judge.yosupo.jp/submission/189742
*/
// ---- gcd ----
uint64_t gcd_stein_impl( uint64_t x, uint64_t y ) {
if( x == y ) { return x; }
const uint64_t a = y - x;
const uint64_t b = x - y;
const int n = __builtin_ctzll( b );
const uint64_t s = x < y ? a : b;
const uint64_t t = x < y ? x : y;
return gcd_stein_impl( s >> n, t );
}
uint64_t gcd_stein( uint64_t x, uint64_t y ) {
if( x == 0 ) { return y; }
if( y == 0 ) { return x; }
const int n = __builtin_ctzll( x );
const int m = __builtin_ctzll( y );
return gcd_stein_impl( x >> n, y >> m ) << ( n < m ? n : m );
}
// ---- is_prime ----
uint64_t mod_pow( uint64_t x, uint64_t y, uint64_t mod ) {
uint64_t ret = 1;
uint64_t acc = x;
for( ; y; y >>= 1 ) {
if( y & 1 ) {
ret = __uint128_t(ret) * acc % mod;
}
acc = __uint128_t(acc) * acc % mod;
}
return ret;
}
bool miller_rabin( uint64_t n, const std::initializer_list<uint64_t>& as ) {
return std::all_of( as.begin(), as.end(), [n]( uint64_t a ) {
if( n <= a ) { return true; }
int e = __builtin_ctzll( n - 1 );
uint64_t z = mod_pow( a, ( n - 1 ) >> e, n );
if( z == 1 || z == n - 1 ) { return true; }
while( --e ) {
z = __uint128_t(z) * z % n;
if( z == 1 ) { return false; }
if( z == n - 1 ) { return true; }
}
return false;
});
}
bool is_prime( uint64_t n ) {
if( n == 2 ) { return true; }
if( n % 2 == 0 ) { return false; }
if( n < 4759123141 ) { return miller_rabin( n, { 2, 7, 61 } ); }
return miller_rabin( n, { 2, 325, 9375, 28178, 450775, 9780504, 1795265022 } );
}
// ---- Montgomery ----
class Montgomery {
uint64_t mod;
uint64_t R;
public:
Montgomery( uint64_t n ) : mod(n), R(n) {
for( size_t i = 0; i < 5; ++i ) {
R *= 2 - mod * R;
}
}
uint64_t fma( uint64_t a, uint64_t b, uint64_t c ) const {
const __uint128_t d = __uint128_t(a) * b;
const uint64_t e = c + mod + ( d >> 64 );
const uint64_t f = uint64_t(d) * R;
const uint64_t g = ( __uint128_t(f) * mod ) >> 64;
return e - g;
}
uint64_t mul( uint64_t a, uint64_t b ) const {
return fma( a, b, 0 );
}
};
// ---- Pollard's rho algorithm ----
uint64_t pollard_rho( uint64_t n ) {
if( n % 2 == 0 ) { return 2; }
const Montgomery m( n );
constexpr uint64_t C1 = 1;
constexpr uint64_t C2 = 2;
constexpr uint64_t M = 512;
uint64_t Z1 = 1;
uint64_t Z2 = 2;
retry:
uint64_t z1 = Z1;
uint64_t z2 = Z2;
for( size_t k = M; ; k *= 2 ) {
const uint64_t x1 = z1 + n;
const uint64_t x2 = z2 + n;
for( size_t j = 0; j < k; j += M ) {
const uint64_t y1 = z1;
const uint64_t y2 = z2;
uint64_t q1 = 1;
uint64_t q2 = 2;
z1 = m.fma( z1, z1, C1 );
z2 = m.fma( z2, z2, C2 );
for( size_t i = 0; i < M; ++i ) {
const uint64_t t1 = x1 - z1;
const uint64_t t2 = x2 - z2;
z1 = m.fma( z1, z1, C1 );
z2 = m.fma( z2, z2, C2 );
q1 = m.mul( q1, t1 );
q2 = m.mul( q2, t2 );
}
q1 = m.mul( q1, x1 - z1 );
q2 = m.mul( q2, x2 - z2 );
const uint64_t q3 = m.mul( q1, q2 );
const uint64_t g3 = gcd_stein( n, q3 );
if( g3 == 1 ) { continue; }
if( g3 != n ) { return g3; }
const uint64_t g1 = gcd_stein( n, q1 );
const uint64_t g2 = gcd_stein( n, q2 );
const uint64_t C = g1 != 1 ? C1 : C2;
const uint64_t x = g1 != 1 ? x1 : x2;
uint64_t z = g1 != 1 ? y1 : y2;
uint64_t g = g1 != 1 ? g1 : g2;
if( g == n ) {
do {
z = m.fma( z, z, C );
g = gcd_stein( n, x - z );
} while( g == 1 );
}
if( g != n ) {
return g;
}
Z1 += 2;
Z2 += 2;
goto retry;
}
}
}
void factorize_impl( uint64_t n, std::vector<uint64_t>& ret ) {
if( n <= 1 ) { return; }
if( is_prime( n ) ) { ret.push_back( n ); return; }
const uint64_t p = pollard_rho( n );
factorize_impl( p, ret );
factorize_impl( n / p, ret );
}
std::vector<uint64_t> factorize( uint64_t n ) {
std::vector<uint64_t> ret;
factorize_impl( n, ret );
std::sort( ret.begin(), ret.end() );
return ret;
}
} // namespace fast_factorize
std::vector<std::pair<long long, int>> factorize(long long n){ // 素因数分解
std::vector<std::pair<long long, int>> ans;
auto ps = fast_factorize::factorize(n);
int sz = ps.size();
for (int l = 0, r = 0; l < sz; l = r){
while (r < sz && ps[l] == ps[r]) r++;
ans.emplace_back(ps[l], r-l);
}
return ans;
}
std::vector<long long> divisors(long long n){ // 約数列挙
auto ps = fast_factorize::factorize(n);
int sz = ps.size();
std::vector<long long> ans = {1};
for (int l = 0, r = 0; l < sz; l = r){
while (r < sz && ps[l] == ps[r]) r++;
int e = r - l;
int len = ans.size();
ans.reserve(len*(e+1));
long long mul = ps[l];
while (true){
for (int i = 0; i < len; i++){
ans.emplace_back(ans[i]*mul);
}
if (--e == 0) break;
mul *= ps[l];
}
}
return ans;
}
std::vector<long long> divisors(const std::vector<std::pair<long long, int>> &pes){ // 素因数から約数を列挙
std::vector<long long> ans = {1};
for (auto [p, e] : pes){
int len = ans.size();
ans.reserve(len*(e+1));
long long mul = p;
while (true){
for (int i = 0; i < len; i++){
ans.emplace_back(ans[i]*mul);
}
if (--e == 0) break;
mul *= p;
}
}
return ans;
}
bool is_prime(long long n){ // 素数判定
if (n <= 1) return false;
return fast_factorize::is_prime(n);
}
struct Sieve {
vector<int> primes, factor, mu;
Sieve (int N = 1024){
build(N);
}
void request(int N){
int len = n_max();
if (len >= N) return ;
while (len < N) len <<= 1;
build(len);
}
int n_max(){ return factor.size()-1; }
private:
void build (int N){
primes.clear();
factor.resize(N+1); fill(factor.begin(),factor.end(),0);
mu.resize(N+1); fill(mu.begin(),mu.end(),1);
for(int n = 2; n <= N; n++) {
if (factor[n] == 0){
primes.push_back(n);
factor[n] = n;
mu[n] = -1;
}
for (int p : primes){
if(n * p > N || p > factor[n]) break;
factor[n * p] = p;
mu[n * p] = p == factor[n] ? 0 : -mu[n];
}
}
}
} sieve;
int mobius_sieve(int n){ // メビウス関数
assert(1 <= n);
if (n>sieve.n_max())sieve.request(n);
return sieve.mu[n];
}
bool is_prime_sieve(int n){
if (n <= 2) return n == 2;
if (n>sieve.n_max())sieve.request(n);
return sieve.factor[n] == n;
}
vector<pair<int,int>> prime_factorization_sieve(int n){ // 素因数分解
assert(1 <= n);
if (n>sieve.n_max())sieve.request(n);
vector<int> facts;
while (n > 1){
int p = sieve.factor[n];
facts.push_back(p);
n /= p;
}
vector<pair<int,int>> pes;
int siz = facts.size();
for (int l = 0, r = 0; l < siz; l = r){
while (r < siz && facts[r] == facts[l]) r++;
pes.emplace_back(facts[l],r-l);
}
return pes;
}
vector<int> divisor_enumeration_sieve(int n){ // 約数列挙
auto pes = prime_factorization_sieve(n);
vector<int> divs = {1};
for (auto [p, e] : pes){
vector<int> nxt; nxt.reserve(divs.size() * (e+1));
for (auto x : divs){
for (int tt = 0; tt <= e; tt++){
nxt.push_back(x);
x *= p;
}
}
swap(divs,nxt);
}
return divs;
}
} // namespace noya2
using namespace noya2;
void solve() {
ll Q;
cin>>Q;
rep(_,Q){
ll N;
cin>>N;
ll g=0;
for (auto [p,e]:factorize(N)){
g=gcd(g,e);
}
cout<<g<<endl;
}
return;
}
int main() {
ll T=1;
while (T--){
solve();
}
return 0;
}
こめだわら