有趣的水题
由期望的线性性质,全局期望 = 每个格子的期望之和
由于权值一样,我们优先选概率大的点就好了
用一些数据结构来维护就好了
复杂度$O(k log n)$
#include <set> #include <map> #include <queue> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> namespace remoon { #define re register #define de double #define le long double #define ri register int #define ll long long #define sh short #define pii pair<int, int> #define mp make_pair #define pb push_back #define fi first #define se second #define tpr template <typename ra> #define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++) #define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --) #define gc getchar inline int read() { int p = 0, w = 1; char c = gc(); while(c > '9' || c < '0') { if(c == '-') w = -1; c = gc(); } while(c >= '0' && c <= '9') p = p * 10 + c - '0', c = gc(); return p * w; } int wr[50], rw; #define pc(iw) putchar(iw) tpr inline void write(ra o, char c = ' ') { if(!o) pc('0'); if(o < 0) o = -o, pc('-'); while(o) wr[++ rw] = o % 10, o /= 10; while(rw) pc(wr[rw --] + '0'); pc(c); } tpr inline void cmin(ra &a, ra b) { if(a > b) a = b; } tpr inline void cmax(ra &a, ra b) { if(a < b) a = b; } tpr inline bool ckmin(ra &a, ra b) { return (a > b) ? a = b, 1 : 0; } tpr inline bool ckmax(ra &a, ra b) { return (a < b) ? a = b, 1 : 0; } } using namespace std; using namespace remoon; namespace mod_mod { #define mod 1000000007 inline void inc(int &a, int b) { a += b; if(a >= mod) a -= mod; } inline void dec(int &a, int b) { a -= b; if(a < 0) a += mod; } inline int Inc(int a, int b) { return (a + b >= mod) ? a + b - mod : a + b; } inline int Dec(int a, int b) { return (a - b < 0) ? a - b + mod : a - b; } inline int mul(int a, int b) { return 1ll * a * b % mod; } } using namespace mod_mod; de ans = 0; int n, m, r, k; int nx[10] = { 1, -1, 0, 0 }; int ny[10] = { 0, 0, 1, -1 }; struct node { int x, y; ll c; friend bool operator < (node a, node b) { return a.c < b.c; } }; priority_queue <node> q; map <pii, int> vis; inline bool ck(int x, int y) { if(x < 1 || x > n) return 0; if(y < 1 || y > m) return 0; if(vis[mp(x, y)]) return 0; else return 1; } inline ll solve(int x, int y) { ll X = min(min(x, n - x + 1), min(n - r + 1, r)); ll Y = min(min(y, m - y + 1), min(m - r + 1, r)); return X * Y; } int main() { n = read(); m = read(); r = read(); k = read(); vis[mp(r, r)] = 1; q.push((node){r, r, solve(r, r)}); while(k --) { node now = q.top(); q.pop(); int x = now.x, y = now.y; ans += now.c / (de)(n - r + 1) / (de)(m - r + 1); rep(i, 0, 3) { int dx = x + nx[i], dy = y + ny[i]; if(ck(dx, dy)) { vis[mp(dx, dy)] = 1; q.push((node){dx, dy, solve(dx, dy)}); } } } printf("%.9lf ", ans); return 0; }