intdfs(int sta, int s){ if (vis[sta]) return f[sta]; int& ret = f[sta]; ret = s? -INF: INF; int x = n, y = 0; for (int i = 0; i < n + m - 1; ++i) { if ((sta >> i) & 1) ++y; else --x; if (((sta >> i) & 3) != 2) continue; if (s) ret = max(ret, dfs(sta ^ (3 << i), s ^ 1) + A[x][y]); else ret = min(ret, dfs(sta ^ (3 << i), s ^ 1) - B[x][y]); } return vis[sta] = true, ret; }
intmain(){ #ifndef ONLINE_JUDGE freopen("input.in", "r", stdin); #endif // input scanf("%d%d", &n, &m); for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) scanf("%d", A[i] + j); for (int i = 0; i < n; ++i) for (int j = 0; j < m; ++j) scanf("%d", B[i] + j); // solve int ed = (1 << m) - 1; vis[ed] = true, f[ed] = 0; // output printf("%d\n", dfs(((1 << m) - 1) << n, 1)); return0; }
inlinevoidsolve(){ // pre done init(); for (int i = 1; i <= n; ++i) size[i] = 1; for (int i = n; i; --i) AddEdge(floor(i / K), i); // solve for (int v, i = head[0]; ~i; i = edges[i].nxt) v = edges[i].to, SGT::Mdy(1, 1, n, v, size[v]); sort(A+1, A+1+n); for (int L = 1; L <= n; ++L) { int R = L; while (R < n && A[R+1] == A[L]) ++R; for (int j = R - L + 1; j; --j) { int u = SGT::Qry(1, 1, n, j); Ans[u] = A[L], SGT::Mdy(1, 1, n, u, -size[u]); for (int v, i = head[u]; ~i; i = edges[i].nxt) v = edges[i].to, SGT::Mdy(1, 1, n, v, size[v]); } L = R; } // output for (int i = 1; i <= n; ++i) printf("%d%c", Ans[i], " \n"[i == n]); } }
intmain(){ #ifndef ONLINE_JUDGE freopen("input.in", "r", stdin); #endif scanf("%d%lf", &n, &K); for (int i = 1; i <= n; ++i) read(A[i]); Graph::solve(); return0; }
int n, m, C, S, T; vector<int> A[MAXN][MAXN]; int Ans1[MAXN], Ans2[MAXN], B[MAXN], s[MAXN];
structEdge { int to, flow, cap; Edge() { } Edge(int _v, int _c): to(_v), cap(_c) { flow = 0; } };
structGraph { vector<Edge> edges; vector<int> G[MAXV]; int depth[MAXV], vis[MAXV], Time;
inlinevoidinit(){ edges.clear(); for (int i = 0; i <= n + m + 1; ++i) G[i].clear(); }
inlinevoidAddEdge(int from, int to, int c){ edges.push_back(Edge(to, c)), edges.push_back(Edge(from, 0)); int eidx = edges.size() - 1; G[from].push_back(eidx - 1), G[to].push_back(eidx); } inlinevoidDelEdge(int from, int to){ G[from].pop_back(), G[to].pop_back(); }
boolBFS(){ queue<int> Q; Q.push(S), vis[S] = ++Time, depth[S] = 1; while (!Q.empty()) { int u = Q.front(); Q.pop(); for (size_t i = 0; i < G[u].size(); ++i) { const Edge& e = edges[G[u][i]]; if (vis[e.to] != Time && e.cap > e.flow) vis[e.to] = Time, depth[e.to] = depth[u] + 1, Q.push(e.to); } } return vis[T] == Time; }
intDFS(int u, int a){ if (u == T || !a) return a; int f, flow = 0; for (size_t i = 0; i < G[u].size(); ++i) { Edge& e = edges[G[u][i]]; if (depth[e.to] == depth[u] + 1 && (f = DFS(e.to, min(a, e.cap-e.flow))) > 0) { flow += f, a -= f, e.flow += f, edges[G[u][i]^1].flow -= f; if (!a) break; } } return flow; } } G[MAXN];
inlineboolcheck(int Mid, constint& u){ static Graph now; now = G[Mid - 1], now.AddEdge(S, u, 1); for (int j = 1; j <= s[u]; ++j) for (size_t k = 0; k < A[u][j].size(); ++k) now.AddEdge(u, n + A[u][j][k], 1); return now.BFS(); }
intmain(){ #ifndef ONLINE_JUDGE freopen("input.in", "r", stdin); #endif int Ti; read(Ti), read(C); while (Ti--) { read(n), read(m); // init S = 0, T = n + m + 1; G[0].init(); for (int i = 1; i <= n; ++i) for (int j = 0; j <= m; ++j) A[i][j].clear(); // input for (int i = 1; i <= m; ++i) read(B[i]); for (int x, i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) read(x), A[i][x].push_back(j); for (int i = 1; i <= n; ++i) read(s[i]); // solve for (int i = 1; i <= m; ++i) G[0].AddEdge(n + i, T, B[i]); // Q1 for (int i = 1; i <= n; ++i) { Ans1[i] = 0; G[i] = G[i - 1], G[i].AddEdge(S, i, 1); for (int j = 1; j <= m; ++j) { for (size_t k = 0; k < A[i][j].size(); ++k) G[i].AddEdge(i, n + A[i][j][k], 1); if (G[i].BFS()) { G[i].DFS(S, INF), Ans1[i] = j; break; } for (size_t k = 0; k < A[i][j].size(); ++k) G[i].DelEdge(i, n + A[i][j][k]); } if (!Ans1[i]) Ans1[i] = m + 1; } // Q2 for (int i = 1; i <= n; ++i) { Ans2[i] = 0; if (s[i] >= Ans1[i]) continue; int L = 1, R = i - 1, ans = -1; while (L <= R) { int Mid = (L + R) / 2; if (check(Mid, i)) ans = Mid, L = Mid + 1; else R = Mid - 1; } Ans2[i] = (ans == -1)? i: i - ans; } // output for (int i = 1; i <= n; ++i) printf("%d%c", Ans1[i], " \n"[i == n]); for (int i = 1; i <= n; ++i) printf("%d%c", Ans2[i], " \n"[i == n]); } return0; }
voidMdy(int nd, int L, int R, constint& pos){ if (L == R) returnvoid( dat[nd].d.mn = dat[nd].d.mx = pos ); int Mid = (L + R) / 2; if (pos <= Mid) { if (!dat[nd].lc) dat[nd].lc = ++nidx; Mdy(dat[nd].lc, L, Mid, pos); } else { if (!dat[nd].rc) dat[nd].rc = ++nidx; Mdy(dat[nd].rc, Mid+1, R, pos); } maintain(nd); }
intMrg(int x, int y){ if (!x || !y) return x + y; int nd = ++nidx; dat[nd].lc = Mrg(dat[x].lc, dat[y].lc); dat[nd].rc = Mrg(dat[x].rc, dat[y].rc); returnmaintain(nd), nd; }
Data Qry(int nd, int L, int R, constint& opL, constint& opR){ if (!nd) returnData(); if (opL <= L && R <= opR) return dat[nd].d; int Mid = (L + R) / 2; if (opR <= Mid) returnQry(dat[nd].lc, L, Mid, opL, opR); if (opL > Mid) returnQry(dat[nd].rc, Mid+1, R, opL, opR); returnQry(dat[nd].lc, L, Mid, opL, opR) + Qry(dat[nd].rc, Mid+1, R, opL, opR); }
LL Qry(int nd, int lgt){ int r1 = dat[nd].d.mn, ln = dat[nd].d.mx - lgt + 1; Data d = Qry(nd, 1, n, 1, ln); LL ret = 0; // Case 1 if (d.mx - lgt + 1 >= r1) return0; // Case 2 if (r1 > ln) { ret += dat[nd].d.s1 - 1LL * ln * dat[nd].d.s2; ret += 1LL * (r1 - ln) * (n - lgt) + C2(r1 - ln); return ret; } // Case 3 if (ln < r1 + lgt - 1) { Data p = Data(d.mx, 0, 0, 0) + Qry(nd, 1, n, ln + 1, r1 + lgt - 1); ret += p.s1 - 1LL * ln * p.s2; } int ri = Qry(nd, 1, n, 1, r1 + lgt - 1).mx, ri1 = Qry(nd, 1, n, r1 + lgt, n).mn; if (ri != -MAXN && ri1 != MAXN) ret += max(0LL, 1LL * (r1 - (ri-lgt+1)) * (ri1 - ln)); return ret; } }
namespace SAM { int ch[MAXM][10], len[MAXM], lnk[MAXM], nidx, last; int cnt[MAXM], idx[MAXM];
inlinevoidinit(){ nidx = last = 1; }
inlinevoidinsert(int val, int i){ int nd = ++nidx, p = last; len[nd] = len[last] + 1, SGT::Mdy(rt[nd] = ++SGT::nidx, 1, n, i); while (p && !ch[p][val]) ch[p][val] = nd, p = lnk[p]; if (!p) lnk[nd] = 1; else { int q = ch[p][val]; if (len[q] == len[p] + 1) lnk[nd] = q; else { int nxt = ++nidx; len[nxt] = len[p] + 1, lnk[nxt] = lnk[q]; memcpy(ch[nxt], ch[q], sizeof ch[nxt]); while (p && ch[p][val] == q) ch[p][val] = nxt, p = lnk[p]; lnk[nd] = lnk[q] = nxt; } } last = nd; }
voidbuild(){ for (int i = 1; i <= nidx; ++i) ++cnt[len[i]]; for (int i = 1; i <= n; ++i) cnt[i] += cnt[i-1]; for (int i = 1; i <= nidx; ++i) idx[cnt[len[i]]--] = i; for (int u, i = nidx; i > 1; --i) u = idx[i], rt[lnk[u]] = SGT::Mrg(rt[lnk[u]], rt[u]); for (int i = 1; i <= nidx; ++i) pre[0][i] = lnk[i]; for (int j = 1; j < LOG; ++j) for (int i = 1; i <= nidx; ++i) pre[j][i] = pre[j-1][pre[j-1][i]]; }
inlineintJump(int u, constint& lgt){ for (int j = LOG-1; j >= 0; --j) if (pre[j][u] && len[pre[j][u]] >= lgt) u = pre[j][u]; return u; }
LL Qry(constint& L, constint& R){ int u = Jump(pos[R], R - L + 1); return SGT::Qry(rt[u], R - L + 1); } }