D - Takahashi Unevolved Editorial by Mitsubachi


C++ を使い、公式解説の方針で解く場合にオーバフローを回避する別の方法を紹介します。

カコモンジムとAtcoderジムのどちらに行くとよいかの判定部分で、整数 $Z$ に対し、

  • $Z \times A \leq Z+B$ であるか?
  • を判定しなければならず、 $Z \times A$ は最大で $10^{27}$ 近くになるので、このまま実装すると long long ではオーバーフローしてしまいます。

    そこで

  • $Z \leq \frac{Z+B}{A}$ であるか?
  • と上の条件を言い換えるのが一般的にオーバフローを回避する方法ですが、多倍長整数を使うという方法もあります。

    多倍長整数として、 boost/multiprecision/cpp_int.hpp をincludeすることで使用できる cpp_int を使います。 これは通常の int や long long 型などと同様に扱うことのできる、(メモリが許す限り)上限値がない多倍長整数です。
    演算が $O(1)$ ではないですが、この問題では気にすることなくACすることができます。

    参考記事

    実装例(C++)
    #include<bits/stdc++.h>
    using namespace std;
    
    #include<boost/multiprecision/cpp_int.hpp>
    using namespace boost::multiprecision;
    
    int main(){
      cpp_int x,y,a,b;
      cin>>x>>y>>a>>b;
      cpp_int ans=0;
    
      while(true){
        if(x*a>x+b||x*a>=y){
          break;
        }
        x*=a;
        ans++;
      }
    
      ans+=(y-1-x)/b;
      cout<<ans<<endl;
    }
    

    posted:
    last update: