# 11625: 【原1625】Interesting Bathroom

### 题目描述

author: xzj 原OJ链接：https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1625

## Description

A certain bathroom has N + 2 stalls in a single row; the stalls on the left and right ends are permanently occupied by the bathroom guards. The other N stalls are for users.

Whenever someone enters the bathroom, they try to choose a stall that is as far from other people as possible. To avoid confusion, they follow deterministic rules: For each empty stall S, they compute two values LS and RS, each of which is the number of empty stalls between S and the closest occupied stall to the left or right, respectively. Then they consider the set of stalls with the farthest closest neighbor, that is, those S for which min(LS, RS) is maximal. If there is only one such stall, they choose it; otherwise, they choose the one among those where max(LS, RS) is maximal. If there are still multiple tied stalls, they choose the leftmost stall among those.

K people are about to enter the bathroom; each one will choose their stall before the next arrives. Nobody will ever leave.

When the last person chooses their stall S, what will the values of max(LS, RS) and min(LS, RS) be?

## Input Format

The first line of the input gives the number of test cases, T. T lines follow. Each line describes a test case with two integers N and K, as described above.

## Output Format

For each test case, output one line containing Case #x: y z, where x is the test case number (starting from 1), y is max(LS, RS), and z is min(LS, RS) as calculated by the last person to enter the bathroom for their chosen stall S.

## Sample Input

``````5
4 2
5 2
6 2
1000 1000
1000 1
``````

## Sample Output

``````Case #1: 1 0
Case #2: 1 0
Case #3: 1 1
Case #4: 0 0
Case #5: 500 499
``````

## Hint

``````In Case #1, the first person occupies the leftmost of the middle two stalls, leaving the following configuration (O stands for an occupied stall and . for an empty one): O.O..O. Then, the second and last person occupies the stall immediately to the right, leaving 1 empty stall on one side and none on the other.

In Case #2, the first person occupies the middle stall, getting to O..O..O. Then, the second and last person occupies the leftmost stall.

In Case #3, the first person occupies the leftmost of the two middle stalls, leaving O..O...O. The second person then occupies the middle of the three consecutive empty stalls.

In Case #4, every stall is occupied at the end, no matter what the stall choices are.

In Case #5, the first and only person chooses the leftmost middle stall.
``````

## Limits

``````1 <= T <= 100.
1 <= K <= N.

50% Data:
1 <= N <= 10^3.

75% Data:
1 <= N <= 10^6.

100% Data:
1 <= N <= 10^18.
``````

## zqy2018's solution

``````/*
See the solution at https://github.com/zqy1018/sjtu_oj_solutions/blob/master/solutions/sjtu1625.md
*/
#include <cstdio>
#define INF 2000000000
using namespace std;
typedef long long ll;
int f = 1, x = 0;
char c = getchar();
while(c < '0' || c > '9'){if(c == '-') f = -f; c = getchar();}
while(c >= '0' && c <= '9')x = x * 10 + c - '0', c = getchar();
return f * x;
}
int n, q, ans = {0}, tans;
int at = {0}, nxt, to, cnt = 0;
int at2 = {0}, nxt2, to2, cnt2 = 0;
int par, dep;
bool vis = {0}, typ = {0};
int Find(int x){
return (par[x] == x ? x: (par[x] = Find(par[x])));
}
void Union(int xxxx, int yyyy){
int u = Find(xxxx), v = Find(yyyy);
if (u == v) return ;
par[u] = v;
}
void init(){
for (int i = 1; i < n; ++i){
to[++cnt] = v, nxt[cnt] = at[u], at[u] = cnt;
to[++cnt] = u, nxt[cnt] = at[v], at[v] = cnt;
}
for (int i = 1; i <= q; ++i){
to2[++cnt2] = v, nxt2[cnt2] = at2[u], at2[u] = cnt2;    // u v
to2[++cnt2] = u, nxt2[cnt2] = at2[v], at2[v] = cnt2;    // v u
to2[++cnt2] = u, nxt2[cnt2] = at2[w], at2[w] = cnt2;    // w u
to2[++cnt2] = w, nxt2[cnt2] = at2[u], at2[u] = cnt2;    // u w
to2[++cnt2] = w, nxt2[cnt2] = at2[v], at2[v] = cnt2;    // v w
to2[++cnt2] = v, nxt2[cnt2] = at2[w], at2[w] = cnt2;    // w v
}
}
void dfs(int cur, int fa){
par[cur] = cur;
for (int i = at[cur]; i; i = nxt[i]){
int v = to[i];
if (v == fa) continue;
dep[v] = dep[cur] + 1, dfs(v, cur), Union(v, cur);
}
vis[cur] = true;
for (int i = at2[cur]; i; i = nxt2[i]){
int v = to2[i];
if (i % 6 == 0){
// as a root, determine the type
int u = to2[i - 3], ccnt = 0;
if (Find(u) == cur) ++ccnt;
if (Find(v) == cur) ++ccnt;
if (ccnt == 2) typ[i / 6] = false;  // both in w
else if (ccnt == 1) ans[i / 6] = cur;
else typ[i / 6] = true;

if (vis[v])
tans[i / 2] = Find(v);
}else {
if (!vis[v]) continue;
int iid = (i / 6), idx = i % 6;
if (idx <= 2)
tans[iid * 3 + 1] = Find(v);
else if (idx <= 4)
tans[iid * 3 + 2] = Find(v);
else
tans[iid * 3 + 3] = Find(v);
}
}
}
void solve(){
dep = 0;
dfs(1, 0);
for (int i = 1; i <= q; ++i){
ans[i] = tans[i * 3 - 2];
if (dep[ans[i]] < dep[tans[i * 3 - 1]])
ans[i] = tans[i * 3 - 1];
if (dep[ans[i]] < dep[tans[i * 3]])
ans[i] = tans[i * 3];
}
for (int i = 1; i <= q; ++i)
printf("%d\n", ans[i]);
}
int main(){
init();
solve();
return 0;
}
``````