判断x开pos次方根的精确值:用pow(x,1/pos)开的话,每次开平方根都是保留的整数。会导致精度的缺失,当pos大的话开出来的值就会出现误差。但误差一般在开出来的值 与正确答案的误差在|1|以内。
ll qpow(ll a, ll b) {//快速幂
ll ans = 1;
while(b) {
if(b&1) {
double tmp = 1.0 * INF / ans;
if(a > tmp) return -1;//如果答案超过 long long 直接返回-1;
ans = ans * a;
}
b >>= 1;
if(a > ((ll)1<<31) && b) return -1;//如果答案超过 long long 直接返回-1;
a = a*a;
}
return ans;
}
ll calc(ll x, int pos) {
ll a = (ll)pow((double)x, 1.0/pos);
//计算a, a-1,a+1、三个值pos次幂看那个更接近x,更接近的即为答案。
ll ansl = qpow(a-1, pos);
ll ansm = qpow(a, pos);
ll ansr = qpow(a+1, pos);
if(ansr != -1 && ansr <= x) return a+1;
if(ansm != -1 && ansm <= x) return a;
return a-1;
}
判断 lcm超过long long
ll _lcm(ll a,ll b)
{
if(a==-1||b==-1) return -1; //在之前求lcm的过程中已经超过long long
if(INF/a<b/gcd(a,b)) return -1; //本次求lcm将会爆long long范围
return a/gcd(a,b)*b;
}