SRM664 div1 easy BearPlays
考えたこと
- 操作回数KでO(K)はできないならどうせ周期性という気持ちになる
- 周期性で O(min(A+B, K)) くらいにはなりそうという気持ちになるが足りない
- 適当に実験したら実は周期が短いのがわかるのでは?と思い実験する
- 3*10^6回実行しても周期性がないのがある
- 周期が長すぎて周期性つかえない気持ちになってくる
-----解説を見た----- - 何もわからないので解説を見る
- 小さい方を2倍するとか考えずにとりあえずAを2倍する処理ということにする
- 大きい方を2倍したとしても mod A+B を取るとこれは問題の操作に一致する
- したがってK回操作を行ったときAは ret = A*2^K mod A+B になる
- min(ret, A+B-ret) が答え
どうせ周期性だろうと思ったら違った…
大きい方を2倍したらどうなるか考える発想がなかった
mod A+Bを取るのが全く思いつかなかった
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef vector<int> VI; typedef vector<VI> VVI; typedef vector<ll> VL; typedef vector<VL> VVL; typedef pair<int, int> PII; #define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i) #define REP(i, n) FOR(i, 0, n) #define ALL(x) x.begin(), x.end() #define IN(a, b, x) (a<=x&&x<b) #define MP make_pair #define PB push_back const int INF = (1LL<<30); const ll LLINF = (1LL<<60); const double PI = 3.14159265359; const double EPS = 1e-12; int MOD = 1000000007; //#define int ll template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); } template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); } int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0}; //二分累乗法 xのe乗 ll binpow(ll x, ll e) { ll a = 1, p = x; while(e > 0) { if(e%2 == 0) {p = (p*p) % MOD; e /= 2;} else {a = (a*p) % MOD; e--;} } return a % MOD; } class BearPlays { public: int pileSize(int A, int B, int K) { MOD = A+B; int ret = A*binpow(2,K)%MOD; return min(ret, A+B-ret); } };