問題:ABC178C
公式解説
公式解説コード
※すでにAC済みなので解法を知りたいという質問ではありません。
質問
公式解説を見ながら提出してWAとなった原因が分からず、
何故型の違いだけでWAになるのか理由が知りたいので分かる方はご教示ください。
よろしくお願いします。
試したこと
テストケースがまだ公開されていないようでどういったテストケースでWA(WA5/AC15/ALL20)となっているのか不明です。
自分は unsigned long long
を使っていたので型の違いを変更する前は、
10^N -9^N -9^N
までの途中の内部的な計算結果のようなもの?が負数になっていることで、
unsigned long long
で扱えない為結果がWAとなっていると推測しました。
そこで次のように計算順序を変更してみましたが結果は変わらずWAでした。
変更前:ll ans=powmod(10,n)-powmod(9,n)-powmod(9,n)+powmod(8,n);
変更後:ll ans=powmod(10,n)+powmod(8,n)-powmod(9,n)-powmod(9,n);
最後に型を全て long long
に変更することでACとなりました。
unsigned long long
の方がlong long
よりも扱える数が大きいし途中計算でも負数になっていないはずです。
何故型の違いだけでWAになるのか理由が分かりません。
例えばN=2の時の手計算は、(10^2=100 - 9^2=81 - 9^2=81 + 8^2=64) = 2 の結果となります。
100-91-91 の時点で一時的に負数になるのは分かるのですが、
計算順序を変えると、(10^2=100 + 8^2=64- 9^2=81 - 9^2=81) = 2 当然同じ結果ですが、
途中計算では100 + 64 - 81 -81 と左から順に計算していれば負数になることはありません。
この部分以外で型が影響している箇所は無いと思ったのですが何かお気づきになりましたらご教示ください。
#追記:
※回答頂き途中計算を手計算したところ負数になっていました。
累乗計算の結果が負数にならないという思い込みから%MODの剰余で負数になることを想定出来なかったことが原因の実装ミスでした。
公式コードで long long
を使っている理由がやっと理解出来ました。
ありがとうございました。
C++
1//公式で long longとなっている箇所全てを 2typedef long long ll; 3 4//自分は unsigned long long としていた箇所を全てlong longにしたらACとなった。 5using ull = unsigned long long;
inout
1// unsigned long long; 2// in 3// 1000000 4 5// 907328795 6// 803957911 7// 961835147 8// 961835147 9 10// out 11// 369960420 12 13// using ll = long long; 14// in 15// 1000000 16 17// 907328795 18// 803957911 19// 961835147 20// 961835147 21 22// out 23// 787616419
###公式解説コード
C++
1#include<bits/stdc++.h> 2using namespace std; 3typedef long long ll; 4const ll mod=1000000007; 5 6ll powmod(ll x,ll y){ 7 ll res=1; 8 for(ll i=0;i<y;i++){ 9 res=res*x%mod; 10 } 11 return res; 12} 13int main(){ 14 ll n; 15 cin>>n; 16 ll ans=powmod(10,n)-powmod(9,n)-powmod(9,n)+powmod(8,n); 17 ans%=mod; 18 ans=(ans+mod)%mod; 19 cout<<ans<<"\n"; 20}
INPUT
12
OUTPUT
12
開発環境
Win10 (10.0.18362)
VSC1.48.2
C++17
gcc version 10.2.0 (Rev1, Built by MSYS2 project)
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/13 19:42