@qq290637843
2021-01-08T06:28:52.000000Z
字数 21860
阅读 265
简单题
#include <bits/stdc++.h>std::stringstream iss;std::stringstream oss;std::string instr;using ul = std::uint32_t;using li = std::int32_t;using ull = std::uint64_t;using ll = std::int64_t;ul T;const ul maxn = 1e5;ul n, m;ul rk[maxn + 1];ul fa[maxn + 1];std::map<ul, std::vector<ul>> b;ul getfather(ul x){return x == fa[x] ? x : fa[x] = getfather(fa[x]);}bool connect(ul a, ul b){a = getfather(a);b = getfather(b);if (a == b) {return false;} else if (rk[a] > rk[b]) {fa[b] = a;} else if (rk[b] > rk[a]) {fa[a] = b;} else {fa[a] = b;++rk[b];}return true;}std::vector<ul> edge[maxn + 1];bool al[maxn + 1];int main(){std::ios::sync_with_stdio(false);std::cin.tie(0);iss.tie(0);oss.tie(0);std::getline(std::cin, instr, char(0));iss.str(instr);iss >> T;for (ul Case = 1; Case <= T; ++Case) {iss >> n >> m;b.clear();for (ul i = 1; i <= n; ++i) {al[i] = false;edge[i].resize(0);ul t;iss >> t;b[t].push_back(i);rk[i] = 0;fa[i] = i;}for (ul i = 1; i <= m; ++i) {ul u, v;iss >> u >> v;edge[u].push_back(v);edge[v].push_back(u);}b[0];ul cnt = 0;ull ans = 0;for (auto it = b.rbegin(), nit = std::next(it); nit != b.rend(); it = nit, ++nit) {for (ul u : it->second) {++cnt;al[u] = true;for (ul v : edge[u]) {if (!al[v]) {continue;}if (connect(u, v)) {--cnt;}}}ans += ull(cnt) * (it->first - nit->first);}oss << ans << '\n';}std::cout << oss.str();return 0;}
官方题解如下:

#include <bits/stdc++.h>std::stringstream iss;std::stringstream oss;std::string instr;using ul = std::uint32_t;using li = std::int32_t;using ull = std::uint64_t;using ll = std::int64_t;ul T;const ul maxn = 600;ul n, k;ul a[maxn + 1];const ul mod = 1e9 + 7;ul plus(ul a, ul b){return a + b < mod ? a + b : a + b - mod;}ul minus(ul a, ul b){return a < b ? a + mod - b : a - b;}ul mul(ul a, ul b){return ull(a) * ull(b) % mod;}class counter {public:ul len = 0;ul cnt = 0;counter()=default;counter(ul a, ul b): len(a), cnt(b) {}};std::vector<counter> f[2][maxn + 1][3];std::vector<counter> tmp;int main(){std::ios::sync_with_stdio(false);std::cin.tie(0);iss.tie(0);oss.tie(0);std::getline(std::cin, instr, char(0));iss.str(instr);iss >> T;for (ul Case = 1; Case <= T; ++Case) {iss >> n >> k;for (ul i = 1; i <= n; ++i) {iss >> a[i];}std::sort(a + 1, a + n + 1);for (ul j = 1; j <= n; ++j) {for (ul t = 0; t <= 2; ++t) {f[1][j][t].resize(0);}}f[1][4][0] = std::vector<counter>(1, counter(0, 1));f[1][5][1] = std::vector<counter>(1, counter(0, 2));for (ul i = 1; i + 1 <= n; ++i) {for (ul j = 1; j <= i + 1; ++j) {for (ul t = 0; t <= 2; ++t) {f[i + 1 & 1][j][t].resize(0);}}for (ul j = 1; j <= i; ++j) {for (ul t = 0; t <= 2; ++t) {ul tmp = (j + j - t) * (a[i + 1] - a[i]);for (const auto& c : f[i & 1][j][t]) {if (j + 1 > t) {f[i + 1 & 1][j + 1][t].push_back(counter(c.len + tmp, mul(c.cnt, j + 1 - t)));}if (2 > t) {f[i + 1 & 1][j + 1][t + 1].push_back(counter(c.len + tmp, mul(c.cnt, 2 - t)));}if (j > 1) {f[i + 1 & 1][j - 1][t].push_back(counter(c.len + tmp, mul(c.cnt, j - 1)));}if (j + j > t) {f[i + 1 & 1][j][t].push_back(counter(c.len + tmp, mul(c.cnt, j + j - t)));}if (2 > t) {f[i + 1 & 1][j][t + 1].push_back(counter(c.len + tmp, mul(c.cnt, 2 - t)));}}}}for (ul j = 1; j <= i + 1; ++j) {for (ul t = 0; t <= 2; ++t) {std::sort(f[i + 1 & 1][j][t].begin(), f[i + 1 & 1][j][t].end(), [](const counter& a, const counter& b){return a.len > b.len;});tmp.resize(0);for (const auto& c : f[i + 1 & 1][j][t]) {if (tmp.empty() || c.len != tmp.back().len) {if (tmp.size() == k) {break;}tmp.push_back(c);} else {tmp.back().cnt = plus(tmp.back().cnt, c.cnt);}}std::swap(tmp, f[i + 1 & 1][j][t]);}}}for (ul i = 0; i != k; ++i) {if (i >= f[n & 1][6][2].size()) {oss << "-1\n";} else {oss << f[n & 1][7][2][i].len << ' ' << f[n & 1][8][2][i].cnt << '\n';}}}std::cout << oss.str();return 0;}
官方题解如下:
来估计一下到底需要取到多少。姑且假设随机数生成器能做到完全独立(虽然实际做不到,但这是没办法的)。现在设执行了次实验(足够大),故对于个颜色,其颜色权值的最小值在次实验的平均值近似为正态分布,。
对于两个符合正态分布的随机变量(不保证独立),且,则有如下上界
于是如果取为,,正确概率至少能大于一半。
然而实际上,取这么大会超时,所以,我只能选择取到,但我不知道怎么证明取到是足够的
#include <bits/stdc++.h>using ul = std::uint32_t;using li = std::int32_t;using ull = std::uint64_t;using ll = std::int64_t;std::mt19937 rnd;ul T;ul n, m;ul cnt;const ul maxn = 5e5;ul col[maxn + 1];const ul k = 35;ul w[maxn + 1][k + 1];ul head[maxn + 1];class edge {public:ul to = 0;ul next = 0;edge()=default;edge(ul a, ul b): to(a), next(b) {}};ul tot;edge edges[maxn + maxn];ul bigson[maxn + 1];ul fa[maxn + 1];ul size[maxn + 1];ul depth[maxn + 1];ul hvhd[maxn + 1];ul lsiz[maxn + 1];void search1(ul curr, ul prev){bigson[curr] = 0;size[curr] = 1;ul mxsz = 0;for (ul nextid = head[curr]; nextid; nextid = edges[nextid].next) {ul next = edges[nextid].to;if (next == prev) {continue;}search1(next, curr);size[curr] += size[next];if (size[next] > mxsz) {mxsz = size[next];bigson[curr] = next;}}lsiz[curr] = size[curr];if (bigson[curr]) {lsiz[curr] -= size[bigson[curr]];}}void search2(ul curr, ul prev){fa[curr] = prev;for (ul nextid = head[curr]; nextid; nextid = edges[nextid].next) {ul next = edges[nextid].to;if (next == prev) {continue;}if (next == bigson[curr]) {hvhd[next] = hvhd[curr];} else {hvhd[next] = next;}depth[next] = depth[curr] + 1;search2(next, curr);}}ul lson[maxn + 1];ul rson[maxn + 1];ul lbound[maxn + 1];ul rbound[maxn + 1];ul tree[maxn + 1][k + 1];const ul inf = ~ul(0);void query(ul l, ul r, ul curr, ul ret[]){if (l <= lbound[curr] && r >= rbound[curr]) {for (ul i = 1; i <= k; ++i) {ret[i] = std::min(ret[i], tree[curr][i]);}return;}if (l <= depth[curr] && r >= depth[curr]) {for (ul i = 1; i <= k; ++i) {ret[i] = std::min(ret[i], w[col[curr]][i]);}}if (l < depth[curr] && lson[curr]) {query(l, r, lson[curr], ret);}if (r > depth[curr] && rson[curr]) {query(l, r, rson[curr], ret);}}void build(ul curr){std::memcpy(tree[curr] + 1, w[col[curr]] + 1, sizeof(ul) * k);if (lson[curr]) {build(lson[curr]);for (ul i = 1; i <= k; ++i) {tree[curr][i] = std::min(tree[curr][i], tree[lson[curr]][i]);}}if (rson[curr]) {build(rson[curr]);for (ul i = 1; i <= k; ++i) {tree[curr][i] = std::min(tree[curr][i], tree[rson[curr]][i]);}}}void change(ul pos, ul curr, ul y){if (depth[curr] > pos) {change(pos, lson[curr], y);} else if (depth[curr] < pos) {change(pos, rson[curr], y);}std::memcpy(tree[curr] + 1, w[col[curr]] + 1, sizeof(ul) * k);if (lson[curr]) {for (ul i = 1; i <= k; ++i) {tree[curr][i] = std::min(tree[curr][i], tree[lson[curr]][i]);}}if (rson[curr]) {for (ul i = 1; i <= k; ++i) {tree[curr][i] = std::min(tree[curr][i], tree[rson[curr]][i]);}}}ul root[maxn + 1];ull query(ul u, ul v){static ul ret[k + 1];for (ul i = 1; i <= k; ++i) {ret[i] = inf;}while (true) {if (hvhd[u] == hvhd[v]) {query(std::min(depth[u], depth[v]), std::max(depth[u], depth[v]), root[hvhd[u]], ret);break;}if (depth[hvhd[u]] > depth[hvhd[v]]) {std::swap(u, v);}query(depth[hvhd[v]], depth[v], root[hvhd[v]], ret);v = fa[hvhd[v]];}ull sret = 0;for (ul i = 1; i <= k; ++i) {sret += ret[i];}return sret;}ul node[maxn + 1];ul deal(ul l, ul r){if (l == r + 1) {return 0;}ul sum = 0;for (ul i = l; i <= r; ++i) {sum += lsiz[node[i]];}ul sum2 = 0;for (ul i = l; i <= r; ++i) {sum2 += lsiz[node[i]];if (sum2 + sum2 >= sum) {lson[node[i]] = deal(l, i - 1);rson[node[i]] = deal(i + 1, r);lbound[node[i]] = l;rbound[node[i]] = r;return node[i];}}}ul prevtime = 0;double gettime(){ul tmp = std::clock();double ret = double(tmp - prevtime) / CLOCKS_PER_SEC;prevtime = tmp;return ret;}int main(){rnd.seed(std::time(0));std::scanf("%u", &T);for (ul Case = 1; Case <= T; ++Case) {std::scanf("%u%u", &n, &m);for (ul i = 1; i <= n; ++i) {for (ul j = 1; j <= k; ++j) {w[i][j] = rnd();}}tot = 0;for (ul i = 1; i <= n; ++i) {std::scanf("%u", &col[i]);head[i] = 0;}for (ul i = 1; i <= n - 1; ++i) {ul u, v;std::scanf("%u%u", &u, &v);++tot;edges[tot].to = v;edges[tot].next = head[u];head[u] = tot;++tot;edges[tot].to = u;edges[tot].next = head[v];head[v] = tot;}search1(1, 0);hvhd[1] = 1;depth[1] = 0;search2(1, 0);for (ul i = 1; i <= n; ++i) {if (hvhd[i] != i) {continue;}ul md = 0;for (ul j = i; j; j = bigson[j]) {node[depth[j]] = j;md = depth[j];}root[i] = deal(depth[i], md);}for (ul i = 1; i <= n; ++i) {if (i == hvhd[i]) {build(root[i]);}}cnt = 0;for (ul i = 1; i <= m; ++i) {ul q;std::scanf("%u", &q);if (q == 1) {ul x, y;std::scanf("%u%u", &x, &y);x ^= cnt;y ^= cnt;col[x] = y;change(depth[x], root[hvhd[x]], y);} else {ul a, b, c, d;std::scanf("%u%u%u%u", &a, &b, &c, &d);a ^= cnt;b ^= cnt;c ^= cnt;d ^= cnt;if (query(a, b) < query(c, d)) {++cnt;std::printf("Yes\n");} else {std::printf("No\n");}}}}prevtime = 0;return 0;}
官方题解如下:

#include <bits/stdc++.h>using ul = std::uint32_t;using li = std::int32_t;using ull = std::uint64_t;using ll = std::int64_t;using pulul = std::pair<ul, ul>;ul prevtime = 0;double gettime(){ul tmp = std::clock();double ret = double(tmp - prevtime) / CLOCKS_PER_SEC;prevtime = tmp;return ret;}std::mt19937 rnd;const ul mod = 1e9 + 7;ul plus(ul a, ul b){return a + b < mod ? a + b : a + b - mod;}ul minus(ul a, ul b){return a < b ? a + mod - b : a - b;}ul mul(ul a, ul b){return ull(a) * ull(b) % mod;}const ul maxn = 400;ul T;ul a[maxn + 1][maxn + 1];ul n;ul q;ul ans11[maxn + 1][maxn + 1];ul ansnn[maxn + 1][maxn + 1];pulul f[maxn + 1][maxn + 1];pulul fr[maxn + 1][maxn + 1];pulul fl[maxn + 1][maxn + 1];class node {public:ul hash = 0;ul val = 0;ul cnt = 0;ul lson = 0;ul rson = 0;node()=default;};ul tot = 0;node tree[ul(1e7)];ul basepow[maxn * maxn + 1];ul n2pow[maxn + maxn + 1];void insert(ul pos, ul& root, ul l, ul r){++tot;tree[tot] = tree[root];root = tot;tree[root].hash = plus(tree[root].hash, basepow[pos]);tree[root].val = plus(tree[root].val, n2pow[pos]);++tree[root].cnt;if (l == r) {return;}ul mid = l + r >> 1;if (pos <= mid) {insert(pos, tree[root].lson, l, mid);} else {insert(pos, tree[root].rson, mid + 1, r);}}bool compare(ul x, ul y, ul l, ul r){if (l == r) {return tree[x].cnt < tree[y].cnt;}if (tree[tree[x].rson].hash != tree[tree[y].rson].hash) {return compare(tree[x].rson, tree[y].rson, (l + r >> 1) + 1, r);} else {return compare(tree[x].lson, tree[y].lson, l, l + r >> 1);}}bool compare(ul x1, ul x2, ul y1, ul y2, ul l, ul r){if (l == r) {return tree[x1].cnt + tree[x2].cnt < tree[y1].cnt + tree[y2].cnt;}if (plus(tree[tree[x1].rson].hash, tree[tree[x2].rson].hash) != plus(tree[tree[y1].rson].hash, tree[tree[y2].rson].hash)) {return compare(tree[x1].rson, tree[x2].rson, tree[y1].rson, tree[y2].rson, (l + r >> 1) + 1, r);} else {return compare(tree[x1].lson, tree[x2].lson, tree[y1].lson, tree[y2].lson, l, l + r >> 1);}}int main(){rnd.seed(std::time(0));std::scanf("%u", &T);for (ul Case = 1; Case <= T; ++Case) {tot = 0;std::scanf("%u%u", &n, &q);ul base = rnd() % mod;basepow[0] = 1;n2pow[0] = 1;for (ul i = 1; i <= n * n; ++i) {basepow[i] = mul(basepow[i - 1], base);n2pow[i] = mul(n2pow[i - 1], n * n);}for (ul i = 1; i <= n; ++i) {for (ul j = 1; j <= n; ++j) {std::scanf("%u", &a[i][j]);}}for (ul i = 1; i <= n; ++i) {for (ul j = 1; j <= n; ++j) {if (i == 1) {if (j == 1) {ans11[i][j] = 0;} else {ans11[i][j] = ans11[i][j - 1];}} else {if (j == 1) {ans11[i][j] = ans11[i - 1][j];} else {ans11[i][j] = compare(ans11[i - 1][j], ans11[i][j - 1], 1, n * n) ? ans11[i][j - 1] : ans11[i - 1][j];}}insert(a[i][j], ans11[i][j], 1, n * n);}}for (ul i = n; i >= 1; --i) {for (ul j = n; j >= 1; --j) {if (i == n) {if (j == n) {ansnn[i][j] = 0;} else {ansnn[i][j] = ansnn[i][j + 1];}} else {if (j == n) {ansnn[i][j] = ansnn[i + 1][j];} else {ansnn[i][j] = compare(ansnn[i + 1][j], ansnn[i][j + 1], 1, n * n) ? ansnn[i][j + 1] : ansnn[i + 1][j];}}f[i][j] = pulul(ans11[i][j], ansnn[i][j]);insert(a[i][j], ansnn[i][j], 1, n * n);fl[i][j] = f[i][j];if (i != n && j != 1) {fl[i][j] = compare(fl[i][j].first, fl[i][j].second, fl[i + 1][j - 1].first, fl[i + 1][j - 1].second, 1, n * n) ? fl[i + 1][j - 1] : fl[i][j];}}}for (ul i = 1; i <= n; ++i) {for (ul j = 1; j <= n; ++j) {fr[i][j] = f[i][j];if (i != 1 && j != n) {fr[i][j] = compare(fr[i][j].first, fr[i][j].second, fr[i - 1][j + 1].first, fr[i - 1][j + 1].second, 1, n * n) ? fr[i - 1][j + 1] : fr[i][j];}}}for (ul i = 1; i <= q; ++i) {ul xl, xr, yl, yr;std::scanf("%u%u%u%u", &xl, &xr, &yl, &yr);pulul tmp(0, 0);if (xr != n && yl != 1) {tmp = compare(tmp.first, tmp.second, fl[xr + 1][yl - 1].first, fl[xr + 1][yl - 1].second, 1, n * n) ? fl[xr + 1][yl - 1] : tmp;}if (xl != 1 && yr != n) {tmp = compare(tmp.first, tmp.second, fr[xl - 1][yr + 1].first, fr[xl - 1][yr + 1].second, 1, n * n) ? fr[xl - 1][yr + 1] : tmp;}std::printf("%u\n", plus(tree[tmp.first].val, tree[tmp.second].val));}}return 0;}
简单题
#include <bits/stdc++.h>using ul = std::uint32_t;using li = std::int32_t;using ull = std::uint64_t;using ll = std::int64_t;ul T;ul n;li m;const ul maxn = 50;const li liinf = (li(1) << 31) - 1;const ll llinf = (ll(1) << 63) - 1;class achieve_t {public:ul to = 0;ll sigma = 0;achieve_t()=default;achieve_t(ul to, ll sigma): to(to), sigma(sigma) {}};bool operator<(const achieve_t& a, const achieve_t& b){return a.sigma > b.sigma;}class mcmf {public:class edge_t {public:ul to = 0;li cap = 0;ll cost = 0;edge_t()=default;edge_t(ul to, li cap, ll cost): to(to), cap(cap), cost(cost) {}};class node_t {public:ll pi;ll sigma;ul p;li a;ul vis;std::vector<ul> edge;};node_t node[maxn + maxn * maxn + 2];edge_t edge[maxn * maxn + maxn + maxn * maxn << 1];std::priority_queue<achieve_t> heap;std::queue<ul> queue;ul tim = 0;ul n, m;void init(ul n) {this->n = n;for (ul i = 0; i != n; ++i) {node[i].edge.resize(0);node[i].pi = 0;}m = 0;}void addedge(ul from, ul to, li cap, ll cost) {edge[m] = edge_t(to, cap, cost);++m;edge[m] = edge_t(from, 0, -cost);++m;node[from].edge.push_back(m - 2);node[to].edge.push_back(m - 1);}bool dikstra(ul s, ul t, li& flow, ll& cost) {for (ul i = 0; i != n; ++i) {node[i].sigma = llinf;}while (heap.size()) {heap.pop();}heap.push(achieve_t(s, 0));node[s].sigma = 0;while (heap.size()) {auto ach = heap.top();heap.pop();if (ach.sigma > node[ach.to].sigma) {continue;}for (ul i : node[ach.to].edge) {edge_t& e = edge[i];if (e.cap > 0 && node[e.to].sigma > ach.sigma + e.cost + node[ach.to].pi - node[e.to].pi) {node[e.to].sigma = ach.sigma + e.cost + node[ach.to].pi - node[e.to].pi;heap.push(achieve_t(e.to, ach.sigma + e.cost + node[ach.to].pi - node[e.to].pi));}}}if (node[t].sigma == llinf) {return false;}while (queue.size()) {queue.pop();}++tim;node[s].p = -1;node[s].a = liinf;queue.push(s);node[s].vis = tim;while (queue.size()) {ul curr = queue.front();queue.pop();for (ul i : node[curr].edge) {edge_t& e = edge[i];ul nex = e.to;if (e.cap > 0 && node[nex].vis != tim && node[nex].sigma == node[curr].sigma + e.cost + node[curr].pi - node[nex].pi) {node[nex].p = i;node[nex].a = std::min(node[curr].a, e.cap);node[nex].vis = tim;queue.push(nex);}}}flow += node[t].a;cost += ll(node[t].sigma + node[t].pi - node[s].pi) * node[t].a;ul u = t;while (u != s) {edge[node[u].p].cap -= node[t].a;edge[node[u].p ^ 1].cap += node[t].a;u = edge[node[u].p ^ 1].to;}for (ul i = 0; i != n; ++i) {node[i].pi = node[i].sigma == llinf ? llinf : node[i].pi + node[i].sigma;}return true;}ll mincost(ul s, ul t) {li flow = 0;ll cost = 0;while (dikstra(s, t, flow, cost));return cost;}};mcmf graph;ll a[maxn + 1], b[maxn + 1], c[maxn + 1];std::vector<li> need[maxn + 1];std::vector<ul> al;using pulull = std::pair<ul, ull>;std::vector<pulull> set;std::map<ul, ul> id;int main(){std::scanf("%u", &T);for (ul Case = 1; Case <= T; ++Case) {std::scanf("%u%d", &n, &m);al.resize(0);for (ul i = 1; i <= n; ++i) {std::scanf("%lld%lld%lld", &a[i], &b[i], &c[i]);need[i].resize(0);ll tmp = -2 * a[i];if (b[i] > tmp) {for (ul j = 1; j <= m && j <= n; ++j) {need[i].push_back(j);al.push_back(j);}} else if (b[i] < m * tmp) {for (ul j = m; m - j + 1 <= n && j >= 1; --j) {need[i].push_back(j);al.push_back(j);}} else {set.resize(0);for (ll j = b[i] / tmp - 100; j <= b[i] / tmp + 100; ++j) {if (j < 1) {continue;}if (j > m) {continue;}set.push_back(pulull(j, a[i] * j * j + b[i] * j + c[i]));}std::sort(set.begin(), set.end(), [](const pulull& a, const pulull& b){return a.second < b.second;});set.resize(std::min(ul(n), ul(m)));for (auto p : set) {need[i].push_back(p.first);al.push_back(p.first);}}}std::sort(al.begin(), al.end());al.resize(std::unique(al.begin(), al.end()) - al.begin());ul tim = n;for (auto a : al) {++tim;id[a] = tim;}++tim;graph.init(tim + 1);for (ul i = 1; i <= n; ++i) {graph.addedge(0, i, 1, 0);for (ll j : need[i]) {graph.addedge(i, id[j], 1, a[i] * j * j + b[i] * j + c[i]);}}for (auto a : al) {graph.addedge(id[a], tim, 1, 0);}li flow = 0;ll cost = 0;for (li i = 1; i <= n; ++i) {if (i != 1) {std::putchar(' ');}while (i > flow) {graph.dikstra(0, tim, flow, cost);}std::printf("%lld", cost);}std::putchar('\n');}return 0;}
简单题
#include <bits/stdc++.h>using ul = std::uint32_t;using li = std::int32_t;using ull = std::uint64_t;using ll = std::int64_t;using llf = long double;ul T;const ul maxn = 1e6;ull fib[maxn + maxn + 2];int main(){fib[0] = fib[1] = 1;for (ul i = 2; i <= maxn + maxn + 1; ++i) {fib[i] = fib[i - 1] + fib[i - 2];}std::scanf("%u", &T);for (ul Case = 1; Case <= T; ++Case) {ul al, bl, cl;ull a = 0, b = 0, c = 0;ul ai, bi, ci;std::scanf("%u", &al);for (ul i = 1; i <= al; ++i) {std::scanf("%u", &ai);if (ai) {a += fib[i];}}std::scanf("%u", &bl);for (ul i = 1; i <= bl; ++i) {std::scanf("%u", &bi);if (bi) {b += fib[i];}}std::scanf("%u", &cl);for (ul i = 1; i <= cl; ++i) {std::scanf("%u", &ci);if (ci) {c += fib[i];}}ull t = a * b - c;for (ul i = 1; ; ++i) {if (fib[i] == t) {std::printf("%u\n", i);break;}}}return 0;}
官方题解如下:

#include <bits/stdc++.h>using ul = std::uint32_t;using li = std::int32_t;using ull = std::uint64_t;using ll = std::int64_t;ul T;const ul maxn = 2e4;const ul maxk = 20;ul n, k;class edge {public:ul a = 0;ul b = 0;ul to = 0;edge()=default;edge(ul x, ul y, ul z): to(x), a(y), b(z) {}};std::vector<edge> edges[maxn + 1];ull f[maxn + 1][maxk + 1];ull tmpf[maxk + 1];ull initf[maxk + 1];const ull inf = 2e13;ull bound;ul search(ul curr, ul prev){std::memcpy(f[curr], initf, sizeof(ull) * (k + 1));f[curr][0] = 0;ul currcnt = 0;for (const auto& e : edges[curr]) {ul next = e.to;if (next == prev) {continue;}ul nextcnt = search(next, curr);std::memcpy(tmpf, initf, sizeof(ull) * (k + 1));for (ul x = 0; x <= k && x <= currcnt; ++x) {if (f[curr][x] == inf) {continue;}for (ul y = 0; x + y <= k && y <= nextcnt; ++y) {if (f[next][y] == inf) {continue;}if (f[curr][x] + f[next][y] + e.b <= bound) {tmpf[x + y] = std::min(tmpf[x + y], std::max(f[curr][x], f[next][y] + e.b));}if (x + y != k && f[curr][x] + f[next][y] + e.a <= bound) {tmpf[x + y + 1] = std::min(tmpf[x + y + 1], std::max(f[curr][x], f[next][y] + e.a));}}}std::memcpy(f[curr], tmpf, sizeof(ull) * (k + 1));currcnt += nextcnt + 1;}return currcnt;}int main(){for (ul i = 0; i <= maxk; ++i) {initf[i] = inf;}std::scanf("%u", &T);for (ul Case = 1; Case <= T; ++Case) {std::scanf("%u%u", &n, &k);for (ul i = 1; i <= n; ++i) {edges[i].resize(0);}for (ul i = 1; i <= n - 1; ++i) {ul u, v, a, b;std::scanf("%u%u%u%u", &u, &v, &a, &b);edges[u].push_back(edge(v, a, b));edges[v].push_back(edge(u, a, b));}ull l = n - 2, r = 2e13;while (l + 1 != r) {bound = l + r >> 1;search(1, 0);if (f[1][k] == inf) {l = bound;} else {r = bound;}}std::printf("%llu\n", r);}return 0;}
官方题解如下:

#include <bits/stdc++.h>using ul = std::uint32_t;using li = std::int32_t;using ull = std::uint64_t;using ll = std::int64_t;ul T;const ul maxn = 1e5;const ul maxm = 1e5;ul n, m;ul a[maxn + maxm + 1];ull b[maxn + maxm + 1];ul l[maxn + maxm + 1];bool erased[maxn + maxm + 1];ull ans[maxm + 1];ul tot;ul x[maxm + 1];const ul sz = 1 << 17;std::vector<ul> tos[sz << 1];std::vector<ul> froms[sz << 1];void insert(ul l, ul r, ul v){for (l = l - 1 | sz, r = r + 1 | sz; l ^ r ^ 1; l >>= 1, r >>= 1) {if (~l & 1) {froms[l ^ 1].push_back(v);}if (r & 1) {froms[r ^ 1].push_back(v);}}}void insert(ul pos, ul v){for (pos |= sz; pos; pos >>= 1) {tos[pos].push_back(v);}}ull f(ull x, ull a, ull b){return (x - a) * (x - a) * (x - a) * (x - a) + b;}const ull inf = 9e18;void deal(ul xl, ul xr, ul fl, ul fr, ul nid){if (xl == xr + 1) {return;}ul mid = xl + xr >> 1;ull tmpans = inf;ul lbound, rbound;for (ul i = fl; i <= fr; ++i) {ull cans = f(x[tos[nid][mid]], a[froms[nid][i]], b[froms[nid][i]]);if (tmpans > cans) {tmpans = cans;lbound = i;rbound = i;} else if (tmpans == cans) {rbound = i;}}deal(xl, mid - 1, fl, lbound, nid);deal(mid + 1, xr, rbound, fr, nid);ans[tos[nid][mid]] = std::min(ans[tos[nid][mid]], tmpans);}int main(){std::scanf("%u", &T);for (ul Case = 1; Case <= T; ++Case) {for (ul i = 0; i != sz + sz; ++i) {tos[i].resize(0);froms[i].resize(0);}std::scanf("%u%u", &n, &m);tot = n;for (ul i = 1; i <= n; ++i) {std::scanf("%u%llu", &a[i], &b[i]);l[i] = 1;erased[i] = false;}for (ul i = 1; i <= m; ++i) {x[i] = 0;ul k;std::scanf("%u", &k);if (k == 1) {++tot;std::scanf("%u%llu", &a[tot], &b[tot]);erased[tot] = false;l[tot] = i;} else if (k == 2) {ul t;std::scanf("%u", &t);erased[t] = true;insert(l[t], i, t);} else if (k == 3) {ans[i] = inf;std::scanf("%u", &x[i]);insert(i, i);}}for (ul i = 1; i <= tot; ++i) {if (!erased[i]) {insert(l[i], m, i);}}for (ul i = 1; i != sz + sz; ++i) {if (froms[i].size() && tos[i].size()) {std::sort(froms[i].begin(), froms[i].end(), [](ul s, ul t){return a[s] < a[t];});std::sort(tos[i].begin(), tos[i].end(), [](ul s, ul t){return x[s] < x[t];});deal(0, tos[i].size() - 1, 0, froms[i].size() - 1, i);}}for (ul i = 1; i <= m; ++i) {if (x[i]) {if (ans[i] == inf) {std::printf("-1\n");} else {std::printf("%llu\n", ans[i]);}}}}return 0;}
暴力
#include <bits/stdc++.h>using ul = std::uint32_t;using li = std::int32_t;using ull = std::uint64_t;using ll = std::int64_t;ul T;const ul maxn = 400;const ul maxm = 400;ul n, m, q;ul w[maxn + 1][maxm + 1];std::vector<ul> stack;std::vector<bool> instack(maxn * maxm + 1, false);std::vector<ul> bounds[maxn + 1];char str[4000002];int main(){std::scanf("%u", &T);for (ul Case = 1; Case <= T; ++Case) {std::scanf("%u%u%u", &n, &m, &q);for (ul i = 1; i <= n; ++i) {for (ul j = 1; j <= m; ++j) {std::scanf("%u", &w[i][j]);}}for (ul i = 1; i <= q; ++i) {ul x, y;std::scanf("%u%u%s", &x, &y, str + 1);ul mnx = x, mxx = x;for (ul i = 1; str[i]; ++i) {if (str[i] == 'L') {bounds[x].push_back(y);--x;} else if (str[i] == 'R') {++x;bounds[x].push_back(y);} else if (str[i] == 'D') {--y;} else if (str[i] == 'U') {++y;}mnx = std::min(mnx, x);mxx = std::max(mxx, x);}for (ul x = mnx + 1; x <= mxx; ++x) {std::sort(bounds[x].begin(), bounds[x].end());for (ul i = 0; i != bounds[x].size(); i += 2) {for (ul y = bounds[x][i] + 1; y <= bounds[x][i + 1]; ++y) {if (!instack[w[x][y]]) {instack[w[x][y]] = true;stack.push_back(w[x][y]);}}}bounds[x].resize(0);}std::printf("%u\n", ul(stack.size()));for (ul k : stack) {instack[k] = false;}stack.resize(0);}}return 0;}
暴力
#include <bits/stdc++.h>using ul = std::uint32_t;using li = std::int32_t;using ull = std::uint64_t;using ll = std::int64_t;ul T;const ul maxn = 50;const ul maxk = 50;ul n, k;class eq {public:ul a = 0;ul b = 0;ul c = 0;ul d = 0;eq()=default;};std::vector<eq> eqs[maxk + 1];ull ans = 0;ul a = 100, b = 100, c = 100, d = 100;void search(ul curr){if (curr == k + 1) {ans = std::max(ans, ull(a) * ull(b) * ull(c) * ull(d));return;}if (eqs[curr].size() == 0) {search(curr + 1);return;}for (const auto& e : eqs[curr]) {a += e.a;b += e.b;c += e.c;d += e.d;search(curr + 1);a -= e.a;b -= e.b;c -= e.c;d -= e.d;}}int main(){std::scanf("%u", &T);for (ul Case = 1; Case <= T; ++Case) {std::scanf("%u%u", &n, &k);for (ul i = 1; i <= k; ++i) {eqs[i].resize(0);}for (ul i = 1; i <= n; ++i) {ul t;std::scanf("%u", &t);eqs[t].push_back(eq());std::scanf("%u%u%u%u", &eqs[t].back().a, &eqs[t].back().b, &eqs[t].back().c, &eqs[t].back().d);}std::sort(eqs + 1, eqs + k + 1, [](const std::vector<eq>& a, const std::vector<eq>& b){return a.size() < b.size();});ans = 0;search(1);std::printf("%llu\n", ans);}return 0;}
代码中dp[x][y]表示和的公共子序列要长达,则该公共子序列在中末尾下标最小是多少。
right[i][c]表示中第一个为的字符的下标。
ans[i][y]表示和的公共子序列要长达,则该公共子序列在中末尾下标最小是多少。
#include <bits/stdc++.h>using ul = std::uint32_t;using li = std::int32_t;using ull = std::uint64_t;using ll = std::int64_t;ul T;ul n, m, q;const ul maxn = 1e5;const ul maxm = 20;char a[maxn + 1];char b[maxm + 1];ul dp[maxm + 1][maxm + 1];ul right[maxn + 2][26];ul ans[maxn + 1][maxm + 1];int main(){std::scanf("%u", &T);for (ul Case = 1; Case <= T; ++Case) {std::scanf("%s%s", a + 1, b + 1);n = std::strlen(a + 1);m = std::strlen(b + 1);for (ul i = 0; i != 26; ++i) {right[n + 1][i] = n + 1;}for (ul i = n; i; --i) {std::memcpy(right[i], right[i + 1], sizeof(ul) * 26);right[i][a[i] - 'a'] = i;}for (ul i = 1; i <= n; ++i) {for (ul x = 0; x <= m; ++x) {dp[x][0] = i - 1;for (ul y = 1; y <= x; ++y) {if (x == y) {if (dp[x - 1][y - 1] == n + 1) {dp[x][y] = n + 1;} else {dp[x][y] = right[dp[x - 1][y - 1] + 1][b[x] - 'a'];}} else {dp[x][y] = dp[x - 1][y];if (dp[x - 1][y - 1] != n + 1) {dp[x][y] = std::min(dp[x][y], right[dp[x - 1][y - 1] + 1][b[x] - 'a']);}}}}for (ul x = 0; x <= m; ++x) {ans[i][x] = dp[m][x];}}std::scanf("%u", &q);for (ul i = 1; i <= q; ++i) {ul l, r;std::scanf("%u%u", &l, &r);for (ul i = m; ~i; --i) {if (ans[l][i] <= r) {std::printf("%u\n", r - l + 1 + m - i - i);break;}}}}return 0;}