inlineintrd(){ int x = 0; bool f = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) f |= (c == '-'); for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48); return f ? -x : x; }
inlineintrd(){ int x = 0; bool f = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) f |= (c == '-'); for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48); return f ? -x : x; }
#define N 10007
ll x[N], y[N], f[N];
inlinedoublesqr(double x){return x * x;}
intmain(){ memset(f, 0x3f, sizeof(f)); ll n = rd(), H = rd(), alpha = rd(), beta = rd(); for (int i = 1; i <= n; ++i) {x[i] = rd(); y[i] = rd();} f[1] = alpha * (H - y[1]); ll inf = f[n]; for (int i = 1; i <= n; ++i) { double l = 0, r = H - y[i]; for (int j = i + 1; j <= n; ++j) { double b = 2 * (x[i] + y[j] - x[j] - H); double c = sqr(x[j] - x[i]) + sqr(y[j] - H); double dlt = sqrt(b * b - 4 * c); double L = (-b - dlt) / 2, R = (-b + dlt) / 2; r = min(r, R); if (1.0 * y[j] >= H - 1.0 * (x[j] - x[i]) / 2.0) l = max(l, L); double nwpos = 1.0 * (x[j] - x[i]) / 2.0; if (nwpos >= l - 1e-8 && nwpos <= r + 1e-8) f[j] = min(f[j], f[i] + alpha * (H - y[j]) + beta * (x[j] - x[i]) * (x[j] - x[i])); } } if (f[n] == inf) {puts("impossible"); return0;} printf("%lld\n", f[n]); return0; }
inlineintrd(){ int x = 0; bool f = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) f |= (c == '-'); for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48); return f ? -x : x; }
voidbuild(int rt, int l, int r){ mx[rt].sc = l; if (l == r) return; build(ls, l, mid); build(rs, mid + 1, r); }
voidupd(int rt, int l, int r, int L, int R){ if (L <= l && r <= R) { ++mx[rt].fr; ++tag[rt]; return; } pushdown(rt); if (L <= mid) upd(ls, l, mid, L, R); if (R > mid) upd(rs, mid + 1, r, L, R); pushup(rt); }
voidadd(int l, int r){ if (l <= r) upd(1, 1, n, l, r); else { upd(1, 1, n, 1, r); if (l <= n) upd(1, 1, n, l, n); } }
int tmp[N], pos[N];
inlinevoidwork(int x){ tmp[0] = 0; int tot = 0, mn = 0; for (auto [v, p] : s[x]) { ++tot; tmp[tot] = tmp[tot - 1] + v; mn = min(mn, tmp[tot]); pos[tot] = p; } if (tmp[tot] != 0) return; for (int i = 1; i < tot; ++i) if (tmp[i] == mn) add(pos[i] + 1, pos[i + 1]); if (tmp[tot] == mn) add(pos[tot] + 1, pos[1]); }
intmain(){ n = rd(); for (int i = 1; i <= n; ++i) { char c = getchar(); while (!isalpha(c)) c = getchar(); int x = rd(); s[x].pb(mp((c == 's' ? 1 : -1), i)); } build(1, 1, n); for (int i = 1; i <= 1000000; ++i) if (!s[i].empty()) work(i); printf("%d %d\n", mx[1].sc, mx[1].fr); return0; }
inlineintrd(){ int x = 0; bool f = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) f |= (c == '-'); for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48); return f ? -x : x; }
intfind(int x){return x == f[x] ? x : f[x] = find(f[x]);}
inlinevoidmerge(int x, int y){ x = find(x); y = find(y); f[x] = y; not_tree[y] |= not_tree[x]; }
vector<pii> ans;
queue<int> q;
voidtopo(int x){ for (auto u : s[x]) if (deg[u] == 1 && !circ[u]) {tree[u] = true; q.push(u);} while (!q.empty()) { int u = q.front(); q.pop(); for (int i = hd[u], v; i; i = e[i].nxt) { --deg[v = e[i].to]; if (deg[v] <= 1 && !circ[v] && !tree[v]) { q.push(v); tree[v] = true; } } } for (auto u : s[x]) if (tree[u]) for (int i = hd[u], v; i; i = e[i].nxt) if (!tree[v = e[i].to]) ans.pb(mp(v, u)); }
intmain(){ int n = rd(), m = rd(); for (int i = 1; i <= n; ++i) f[i] = i; for (int i = 1, u, v; i <= m; ++i) { u = rd(); v = rd(); if (find(u) == find(v)) not_tree[find(u)] = circ[u] = circ[v] = true; else {merge(u, v); add(u, v);} } for (int i = 1; i <= n; ++i) s[find(i)].pb(i); for (int i = 1; i <= n; ++i) if (f[i] == i) { if (not_tree[i]) topo(i); elsefor (auto u : s[i]) if (deg[u] == 1) ans.pb(mp(u, e[hd[u]].to)); } sort(all(ans)); printf("%d\n", (int)ans.size()); for (auto [u, v] : ans) printf("%d %d\n", u, v); return0; }
inlineintrd(){ int x = 0; bool f = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) f |= (c == '-'); for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48); return f ? -x : x; }
inlinevoidadd(int u, int v){ e[++tot].to = v; e[tot].nxt = hd[u]; hd[u] = tot; }
intfind(int x){return x == f[x] ? x : f[x] = find(f[x]);}
int vis[N], circ[N], pref[N], ans[N], stk[N], top;
voiddfs(int u, int id){ stk[++top] = u; ++ans[u]; if (top - k > 1) --ans[stk[top - k - 1]]; else { --ans[stk[1]]; int len = k - top + 2; if (len >= m) ++pref[1]; else { int l = id, r = id + len - 1; ++pref[l]; if (r > m) {r -= m; ++pref[1];} if (r < m) --pref[r + 1]; }
} for (int i = hd[u], v; i; i = e[i].nxt) if (vis[v = e[i].to] != 2) {dfs(v, id); ans[u] += ans[v];} --top; }
inlinevoidwork(int u){ m = 0; int t = u; for (; !vis[t]; t = d[t]) vis[t] = 1; for (; vis[t] != 2; t = d[t]) {vis[t] = 2; circ[++m] = t;} rep(i, 1, m) dfs(circ[i], i); rep(i, 1, m) {pref[i] += pref[i - 1]; ans[circ[i]] += pref[i];} rep(i, 1, m) pref[i] = 0; }