一.题目链接:
二.题目大意:
定义
T 组样例 (T < 10)
每组样例给出 n (2 < n < 10) 和 z (1 < z < 1e5)
求 F 的最小值,以及任意一对满足该 F 的 x 和 y 的值.
三.分析:
这数据范围妥妥大数了.
由于 z < 1e5,那我们只需要枚举 y,然后二分 F 的值,确定此时 x 的值.
注意要先将 pow 预处理出来,之后 O(1) 查询即可.
还要注意分类讨论.
详见代码.
四.代码实现:
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Scanner;
import java.util.function.BiFunction;
public class Main
{
public static void main(String[] args)
{
BigInteger zero = new BigInteger("0");
BigInteger one = new BigInteger("1");
BigInteger[][] pow = new BigInteger[100005][15];
for(int i = 1; i <= 100000; ++i)
{
pow[i][0] = one;
for(int j = 1; j <= 10; ++j)
pow[i][j] = pow[i][j - 1].multiply(BigInteger.valueOf(i));
}
BigInteger inf = one;
for(int i = 0; i < 6; ++i)
inf = inf.multiply(pow[10][10]);
Scanner cin = new Scanner(System.in);
int T = cin.nextInt();
while((T--) > 0)
{
int n = cin.nextInt();
int z = cin.nextInt();
int x = 0, y = 0;
BigInteger ans = inf, num;
for(int i = 2; i < z; ++i)
{
int l = 1, r = i - 1, mid;
while(l < r)
{
mid = (l + r + 1) >> 1;
num = pow[mid][n].add(pow[i][n]).subtract(pow[z][n]);
if(num.compareTo(zero) < 0)
l = mid;
else
r = mid - 1;
}
num = pow[l][n].add(pow[i][n]).subtract(pow[z][n]);
if(num.compareTo(zero) >= 0)
{
if(num.compareTo(ans) < 0)
{
ans = num;
x = l;
y = i;
}
}
else
{
num = num.multiply(new BigInteger("-1"));
if(num.compareTo(ans) < 0)
{
ans = num;
x = l;
y = i;
}
if(l < i - 1)
{
++l;
num = pow[l][n].add(pow[i][n]).subtract(pow[z][n]);
if(num.compareTo(ans) < 0)
{
ans = num;
x = l;
y = i;
}
}
}
}
System.out.printf("%d %d ", x, y);
System.out.println(ans);
}
}
}