\(\mathrm{sum}=100+50+80\)html
個人 AK 啊嗚嗚嗚嗚。spa
每秒中有必定的機率浮現幻象,持續 \(x\) 秒的幻象將產生 \(x^2\) 的幻象值。在 \(N\) 秒內指望產生的幻象值是多少。code
麻了,原題。htm
把樹去掉任意條邊,拆成若干棵新樹,求讓每棵新樹的節點數相同的方案數。blog
兩個性質:ip
紀中機子平常爆棧。get
const int N = 1e6 + 10; inline ll Read() { ll x = 0, f = 1; char c = getchar(); while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') f = -f, c = getchar(); while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar(); return x * f; } int n; int head[N], tot; struct edge { int to, nxt; }e[N << 1]; void add(int u, int v) { e[++tot] = (edge){v, head[u]}, head[u] = tot; } int siz[N], fa[N]; int q[N], H, T; inline void bfs(int s) { H = 1, T = 0; q[++T] = s; fa[1] = 0; while(H <= T) { int u = q[H++]; siz[u] = 1; for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].to; if (~fa[v]) continue; fa[v] = u; q[++T] = v; } } for (int i = T; i; i--) { int u = fa[q[i]], v = q[i]; siz[u] += siz[v]; } } int ans; int main() { memset(fa, -1, sizeof fa); n = Read(); for (int i = 1; i < n; i++) { int u = Read(), v = Read(); add(u, v), add(v, u); } bfs(1); for (int i = 1; i * i <= n; i++) { if (n % i) continue; int cnt1 = 0, cnt2 = 0; for (int j = 1; j <= n; j++) cnt1 += siz[j] % i == 0, cnt2 += siz[j] % (n / i) == 0; ans += (cnt1 == n / i) + (cnt2 == i); if(i * i == n) ans--; } printf ("%d\n", ans); return 0; }
先用把 \(\mathrm{mina}\times\mathrm{minb}\) 的子矩陣所有存進堆裏。而後每次取出最優的,並把其向右向下延申的矩陣再存進堆。相同的矩陣用 hash 維護。hash
這個找第 \(k\) 大(小)的想法很像【Luogu P2048】[NOI2010] 超級鋼琴和【Luogu P5283】[十二省聯考2019]異或糉子。it
#define num(i,j) (i-1) * m + j inline ll Read() { ll x = 0, f = 1; char c = getchar(); while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') f = -f, c = getchar(); while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar(); return x * f; } int n, m, mina, minb, k; ll sum[N][N]; struct Matrix { int x1, y1, x2, y2; ll val; Matrix(int X1, int Y1, int X2, int Y2) { x1 = X1, y1 = Y1, x2 = X2, y2 = Y2; val = sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1]; } bool operator < (const Matrix &a) const { return val > a.val; } }; priority_queue<Matrix> q; map<pair<int, int>, int> hash; int main() { n = Read(), m = Read(), mina = Read(), minb = Read(), k = Read(); for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + Read(); for (int i = mina; i <= n; i++) for (int j = minb; j <= m; j++) q.push(Matrix(i - mina + 1, j - minb + 1, i, j)); for (int i = 1; i < k; i++) { if (q.empty()) { puts("-1"); return 0; } Matrix tmp = q.top(); q.pop(); int x1 = tmp.x1, y1 = tmp.y1, x2 = tmp.x2, y2 = tmp.y2; if(x2 < n && !hash[make_pair(num(x1, y1), num(x2 + 1, y2))]) q.push(Matrix(x1, y1, x2 + 1, y2)), hash[make_pair(num(x1, y1), num(x2 + 1, y2))] = 1; if(y2 < m && !hash[make_pair(num(x1, y1), num(x2, y2 + 1))]) q.push(Matrix(x1, y1, x2, y2 + 1)), hash[make_pair(num(x1, y1), num(x2, y2 + 1))] = 1; } if (q.empty()) { puts("-1"); return 0; } printf ("%lld\n", q.top().val); return 0; }