mmrz's library

This documentation is automatically generated by online-judge-tools/verification-helper


Project maintained by mm-rz Hosted on GitHub Pages — Theme by mattgraham

:heavy_check_mark: floor K 乗根
(math/iroot.hpp)

floor K 乗根

使い方

ll iroot(ll n, ll k=2) : $\lfloor \sqrt[k]{n} \rfloor$ を求める( $k$ のデフォルトは $2$ )

Required by

Verified with

Code

#pragma once

#include<cmath>
#include<limits>

unsigned long long iroot(unsigned long long n, int k=2){
	constexpr unsigned long long LIM = std::numeric_limits<unsigned long long>::max();
	if(n <= 1 || k == 1){
		return n;
	}
	if(k >= 64){
		return 1;
	}
	if(k == 2){
		return sqrtl(n);
	}

	if(n == LIM)n--;

	auto safe_mul = [&](unsigned long long &x, unsigned long long &y) -> void {
		if(x <= LIM / y){
			x *= y;
		}else{
			x = LIM;
		}
	};

	auto power = [&](unsigned long long a, int b) -> unsigned long long {
		unsigned long long ret = 1;
		while(b){
			if(b & 1)safe_mul(ret, a);
			safe_mul(a, a);
			b >>= 1;
		}
		return ret;
	};

	unsigned long long ret = (k == 3 ? cbrt(n)-1 : std::pow(n, std::nextafter(1.0/double(k), 0.0)));
	while(power(ret+1, k) <= n)ret++;
	return ret;
}
#line 2 "math/iroot.hpp"

#include<cmath>
#include<limits>

unsigned long long iroot(unsigned long long n, int k=2){
	constexpr unsigned long long LIM = std::numeric_limits<unsigned long long>::max();
	if(n <= 1 || k == 1){
		return n;
	}
	if(k >= 64){
		return 1;
	}
	if(k == 2){
		return sqrtl(n);
	}

	if(n == LIM)n--;

	auto safe_mul = [&](unsigned long long &x, unsigned long long &y) -> void {
		if(x <= LIM / y){
			x *= y;
		}else{
			x = LIM;
		}
	};

	auto power = [&](unsigned long long a, int b) -> unsigned long long {
		unsigned long long ret = 1;
		while(b){
			if(b & 1)safe_mul(ret, a);
			safe_mul(a, a);
			b >>= 1;
		}
		return ret;
	};

	unsigned long long ret = (k == 3 ? cbrt(n)-1 : std::pow(n, std::nextafter(1.0/double(k), 0.0)));
	while(power(ret+1, k) <= n)ret++;
	return ret;
}
Back to top page