#include #define rep(i,n) for (int i=0; i < (int)(n); i++) #define all(c) c.begin(), c.end() using namespace std; typedef long long ll; typedef long double ld; using vi = vector; using vvi = vector; using vl = vector; using vvl = vector; using P = pair; ll solve() { //答えはmax120程度 //BFS書けないか? ll sx,sy,tx,ty; cin>>sx>>sy>>tx>>ty; if(sy > 60 || ty > 60) return abs(sy - ty); //y>60なら左端マスがxの全範囲をカバー //x座標は左端に寄せる { ll dx = 1LL << sy; ll rem = sx % dx; sx -= rem; } { ll dx = 1LL << ty; ll rem = tx % dx; tx -= rem; } //ゴールから直上に上がるケースを事前に格納 map goal; { ll x = tx, y = ty; int d = 0; while(y <= 60) { goal[P(x,y)] = d; y++; ll dx = 1LL << y; ll rem = x % dx; x -= rem; d++; } } //for(auto[p,d]:goal) { auto [x,y] = p; cerr<<'('< dist; dist[P(sx,sy)] = 0; queue

Q; Q.emplace(sx,sy); int ans = 1e9; while(!Q.empty()) { auto[x,y] = Q.front(); Q.pop(); P pos = P(x,y); if(dist[pos] > ans) continue; if(goal.count(pos)) ans = min(ans, dist[pos] + goal[pos]); ll dx = 1LL << y; if(x < tx) { P nxt = P(x+dx, y); if(dist.count(nxt)) continue; dist[nxt] = dist[pos] + 1; Q.push(nxt); } if(tx < x) { P nxt = P(x-dx, y); if(dist.count(nxt)) continue; dist[nxt] = dist[pos] + 1; Q.push(nxt); } //y軸は上方向だけ { dx *= 2; ll rem = x % dx; P nxt = P(x-rem, y+1); if(dist.count(nxt)) continue; dist[nxt] = dist[pos] + 1; Q.push(nxt); } } //for(auto[p,d]:dist) { auto [x,y] = p; cerr<<'('<>T; rep(i,T) cout<