AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC400-C 2^a b^2
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("20");
//5
}
else if (InputPattern == "Input2") {
WillReturn.Add("400");
//24
}
else if (InputPattern == "Input3") {
WillReturn.Add("1234567890");
//42413
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long mN;
static void Main()
{
List<string> InputList = GetInputList();
mN = long.Parse(InputList[0]);
long Answer = 0;
// Aを全探索
int Cnt = 0;
long Beki2 = 2;
while (true) {
long CurrAnswer = DeriveAnswer(Beki2);
if (CurrAnswer == 0) break;
Answer += CurrAnswer;
Beki2 *= 2;
if (++Cnt == 2) break;
}
Console.WriteLine(Answer);
}
// 2べきを引数として、Bの上限を返す
static long DeriveAnswer(long pBeki2)
{
// 1の場合
if (CanAchieve(pBeki2, 1) == false) {
return 0;
}
long L = 1;
long R = long.MaxValue;
while (L + 1 < R) {
long Mid = R / 2;
if (R < long.MaxValue) {
Mid = (L + R) / 2;
}
if (CanAchieve(pBeki2, Mid)) {
L = Mid;
}
else {
R = Mid;
}
}
return L;
}
// N以下にできるかを返す
static bool CanAchieve(long pBeki2, long pB)
{
long Prod = pBeki2;
if (WillOverProd(Prod, pB, mN)) {
return false;
}
Prod *= pB;
if (WillOverProd(Prod, pB, mN)) {
return false;
}
Prod *= pB;
return true;
}
// 2正数の掛け算が、Limitを超えるかを返す
static bool WillOverProd(long pA, long pB, long pLimit)
{
return pA > pLimit / pB;
}
}
解説
2^a * b^2
なので aを全探索し、
bの上限を二分探索することを考えます
N = 2^1 * 平方数
N = 2^2 * 平方数
N = 2^3 * 平方数
N = 2^4 * 平方数
N = 2^5 * 平方数
N = 2^6 * 平方数
N = 2^7 * 平方数
N = 2^8 * 平方数
でNを重複カウントしてしますので
代表を決めて、重複カウントを防ぐことを考えます。
すると
N = 2^1 * 平方数
N = 2^2 * 平方数
N = 2^3 * 平方数 = 2^1 * 2^2 * 平方数
N = 2^4 * 平方数 = 2^2 * 2^2 * 平方数
N = 2^5 * 平方数 = 2^1 * 2^4 * 平方数
N = 2^6 * 平方数 = 2^2 * 2^4 * 平方数
N = 2^7 * 平方数 = 2^1 * 2^6 * 平方数
N = 2^8 * 平方数 = 2^2 * 2^6 * 平方数
指数法則より
2^4は(2^2)の2乗
2^6は(2^3)の2乗
です
なので
N = 2^1 * 平方数
N = 2^2 * 平方数
の通り数の和が、解だと分かります。