《如 何 速 通 一 套 题》12.0
1.《如 何 速 通 一 套 题》12.《如 何 速 通 一 套 题》23.《如 何 速 通 一 套 题》34.《如 何 速 通 一 套 题》 4.15.《如 何 速 通 一 套 题》5.06.《如 何 速 通 一 套 题》5.1bug fixed7.《如 何 速 通 一 套 题》6.08.《如 何 速 通 一 套 题》7.09.《如 何 速 通 一 套 题》8.010.《如 何 速 通 一 套 题》9.011.《如 何 速 通 一 套 题》 10.0
12.《如 何 速 通 一 套 题》12.0
13.《如 何 速 通 一 套 题》13.014.《如 何 速 通 一 套 题》14.015.标题,你懂的(15.0)...16.16.0别问我为什么没有 11.0。补完了 1002 的题我就更 11.0。
邮寄
开场秒掉 AC,用了 1h。
然后开始看 B,死磕了 B 2h 之后磕不动了,然后看 D。
D 忽略了一个关键信息,100 -> 0... 挂大分了。
100+40+75+0=200。
A 旋律的总数
可以固定第一个元素为
然后答案就是
#include <bits/stdc++.h> using namespace std; const int kMod = int(1e9) + 7; int t, n, m; int qpow(int x, int y) { int rs = 1; for(; y; y >>= 1) { if(y & 1) { rs = 1ll * rs * x % kMod; } x = 1ll * x * x % kMod; } return rs; } int main() { freopen("sum.in", "r", stdin); freopen("sum.out", "w", stdout); for(cin >> t; t--; ) { cin >> n >> m; cout << qpow(m, n - 1) << '\n'; } return 0; }
B 水果加工
第十四剪枝。
首先,显然的我们有一个加了可行性剪枝的暴搜:
#include <bits/stdc++.h> #define int long long using namespace std; int n, arr[44], x, y, cx[44], cy[44], dx[44], dy[44], ux[44], uy[44], ans = 1e11; void DFS(int c, int a, int b, int cd, int cu) { //cout << c << ' ' << a << ' ' << b << '\n'; if(c > n) { //cout << cd << ' ' << cu << '\n'; ans = min(ans, cd + cu); return ; } for(int i = 0; i <= arr[c]; i++) { int na = a + (!!i) * cx[c], nb = b + (!!(arr[c] - i)) * cy[c]; if(na <= x && nb <= y) { DFS(c + 1, na, nb, max({cd, dx[c] * i, dy[c] * (arr[c] - i)}), max({cu, ux[c] * i, uy[c] * (arr[c] - i)})); } } } signed main() { freopen("fruit.in", "r", stdin); freopen("fruit.out", "w", stdout); cin >> n; for(int i = 1; i <= n; i++) { cin >> arr[i]; } cin >> x >> y; for(int i = 1; i <= n; i++) { cin >> cx[i]; } for(int i = 1; i <= n; i++) { cin >> cy[i]; } for(int i = 1; i <= n; i++) { cin >> dx[i]; } for(int i = 1; i <= n; i++) { cin >> dy[i]; } for(int i = 1; i <= n; i++) { cin >> ux[i]; } for(int i = 1; i <= n; i++) { cin >> uy[i]; } DFS(1, 0, 0, 0, 0); cout << ans << '\n'; return 0; }
聪明的小同学肯定想到了,我们可以加上简单的最优性剪枝啊!
所以有了 Original + CS11:
#include <bits/stdc++.h> #define int long long using namespace std; int n, arr[44], x, y, cx[44], cy[44], dx[44], dy[44], ux[44], uy[44], ans = 1e11; void DFS(int c, int a, int b, int cd, int cu) { //cout << c << ' ' << a << ' ' << b << '\n'; if(cd + cu > ans) { return ; } if(c > n) { //cout << cd << ' ' << cu << '\n'; ans = min(ans, cd + cu); return ; } for(int i = 0; i <= arr[c]; i++) { int na = a + (!!i) * cx[c], nb = b + (!!(arr[c] - i)) * cy[c]; if(na <= x && nb <= y) { DFS(c + 1, na, nb, max({cd, dx[c] * i, dy[c] * (arr[c] - i)}), max({cu, ux[c] * i, uy[c] * (arr[c] - i)})); } } } signed main() { freopen("fruit.in", "r", stdin); freopen("fruit.out", "w", stdout); cin >> n; for(int i = 1; i <= n; i++) { cin >> arr[i]; } cin >> x >> y; for(int i = 1; i <= n; i++) { cin >> cx[i]; } for(int i = 1; i <= n; i++) { cin >> cy[i]; } for(int i = 1; i <= n; i++) { cin >> dx[i]; } for(int i = 1; i <= n; i++) { cin >> dy[i]; } for(int i = 1; i <= n; i++) { cin >> ux[i]; } for(int i = 1; i <= n; i++) { cin >> uy[i]; } DFS(1, 0, 0, 0, 0); cout << ans << '\n'; return 0; }
然后,更聪明的小伙伴就会发现,这个剪枝力度不够大,还可以再大一点。
于是有了 Original + CS(11 + 21):
#include <bits/stdc++.h> #define int long long using namespace std; int n, arr[44], x, y, cx[44], cy[44], dx[44], dy[44], ux[44], uy[44], ans = 1e11; void DFS(int c, int a, int b, int cd, int cu) { //cout << c << ' ' << a << ' ' << b << '\n'; if(cd + cu >= ans) { return ; } if(c > n) { //cout << cd << ' ' << cu << '\n'; ans = min(ans, cd + cu); return ; } for(int i = 0; i <= arr[c]; i++) { int na = a + (!!i) * cx[c], nb = b + (!!(arr[c] - i)) * cy[c]; if(na <= x && nb <= y) { DFS(c + 1, na, nb, max({cd, dx[c] * i, dy[c] * (arr[c] - i)}), max({cu, ux[c] * i, uy[c] * (arr[c] - i)})); } } } signed main() { freopen("fruit.in", "r", stdin); freopen("fruit.out", "w", stdout); cin >> n; for(int i = 1; i <= n; i++) { cin >> arr[i]; } cin >> x >> y; for(int i = 1; i <= n; i++) { cin >> cx[i]; } for(int i = 1; i <= n; i++) { cin >> cy[i]; } for(int i = 1; i <= n; i++) { cin >> dx[i]; } for(int i = 1; i <= n; i++) { cin >> dy[i]; } for(int i = 1; i <= n; i++) { cin >> ux[i]; } for(int i = 1; i <= n; i++) { cin >> uy[i]; } DFS(1, 0, 0, 0, 0); cout << ans << '\n'; return 0; }
这个时候,更加聪明的巨佬就会发现,可以剪掉一定不是当前最优的状态!
于是有了 Original + CS(11, 21, 22),AC:
#include <bits/stdc++.h> #define int long long using namespace std; struct node { int c, a, b, cd; bool operator <(const node &x) const { return c == x.c? (a == x.a? (b == x.b? cd < x.cd : b < x.b) : a < x.a) : c < x.c; } }; int n, arr[44], x, y, cx[44], cy[44], dx[44], dy[44], ux[44], uy[44], ans = 1e11; map<node, int> mpd; void DFS(int c, int a, int b, int cd, int cu) { //cout << c << ' ' << a << ' ' << b << '\n'; if(cd + cu >= ans) { return ; } if(mpd.find({c, a, b, cd}) != mpd.end() && mpd[{c, a, b, cd}] <= cu) { return ; } mpd[{c, a, b, cd}] = cu; if(c > n) { //cout << cd << ' ' << cu << '\n'; ans = min(ans, cd + cu); return ; } for(int i = 0; i <= arr[c]; i++) { int na = a + (!!i) * cx[c], nb = b + (!!(arr[c] - i)) * cy[c]; if(na <= x && nb <= y) { DFS(c + 1, na, nb, max({cd, dx[c] * i, dy[c] * (arr[c] - i)}), max({cu, ux[c] * i, uy[c] * (arr[c] - i)})); } } } signed main() { freopen("fruit.in", "r", stdin); freopen("fruit.out", "w", stdout); cin >> n; for(int i = 1; i <= n; i++) { cin >> arr[i]; } cin >> x >> y; for(int i = 1; i <= n; i++) { cin >> cx[i]; } for(int i = 1; i <= n; i++) { cin >> cy[i]; } for(int i = 1; i <= n; i++) { cin >> dx[i]; } for(int i = 1; i <= n; i++) { cin >> dy[i]; } for(int i = 1; i <= n; i++) { cin >> ux[i]; } for(int i = 1; i <= n; i++) { cin >> uy[i]; } DFS(1, 0, 0, 0, 0); cout << ans << '\n'; return 0; }
C 最佳位置
显然对于每一个人除了前缀后缀之外就只会坐在一个区间的中间位置。
所以可以直接两个 set
,一个维护有人进来的,一个维护有人出去的,然后根据对应操作直接干就是了。
#include <bits/stdc++.h> using namespace std; int n, m, x, ans[300030]; int gl(int l, int r) { if(l == 1 || r == n) { return r - l + 1; } int mid = (l + r) >> 1; return min(mid - l, r - mid) + 1; } int pos(int l, int r) { if(l == 1) { return 1; } if(r == n) { return n; } return (l + r) >> 1; } struct node { int len, l, r; }; struct cmp1 { bool operator ()(const node &a, const node &b) const { return a.l < b.l; } }; //* struct cmp2 { bool operator ()(const node &a, const node &b) const { return a.len == b.len? a.l < b.l : a.len > b.len; } }; //*/ set<node, cmp1> st1; set<node, cmp2> st2; void ins(int l, int r) { if(l > r) { return ; } int tmp = gl(l, r); st1.insert({tmp, l, r}); st2.insert({tmp, l, r}); } int main() { freopen("location.in", "r", stdin); freopen("location.out", "w", stdout); cin >> n >> m; st1.insert({-1, -1, -1}); st2.insert({-1, -1, -1}); st1.insert({-1, n + 2, n + 2}); st2.insert({-1, n + 2, n + 2}); st1.insert({n, 1, n}); st2.insert({n, 1, n}); for(int i = 1; i <= 2 * m; i++) { cin >> x; if(!ans[x]) { node tmp = *st2.begin(); st2.erase(st2.begin()); st1.erase(tmp); ans[x] = pos(tmp.l, tmp.r); ins(tmp.l, ans[x] - 1); ins(ans[x] + 1, tmp.r); }else { node tmpl = *prev(st1.lower_bound({1, ans[x], ans[x]})), tmpr = *st1.lower_bound({1, ans[x], ans[x]}); int nl = ans[x], nr = ans[x]; if(tmpl.r == ans[x] - 1) { nl = tmpl.l; st1.erase(tmpl); st2.erase(tmpl); } if(tmpr.l == ans[x] + 1) { nr = tmpr.r; st1.erase(tmpr); st2.erase(tmpr); } ins(nl, nr); } /* for(auto i : st1) { cout << i.len << ',' << i.l << ',' << i.r << ' '; } cout << '\n'; for(auto i : st2) { cout << i.len << ',' << i.l << ',' << i.r << ' '; } cout << '\n'; for(int i = 1; i <= m; i++) { cout << ans[i] << ' '; } cout << '\n'; cout << '\n'; //*/ } for(int i = 1; i <= m; i++) { cout << ans[i] << '\n'; } return 0; } /* 9 9 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 */
D 跑步路线
赛时没看到有一个
当
但是这个题要开 __int128_t
qaq
#include <bits/stdc++.h> #define int long long using namespace std; struct node { int u, v, w; }arr[200020]; struct eeee { int v, w; }; int n, m, f[200020], k, t, x, y, fa[200020][22], ddp[200020], dep[200020]; __int128_t ans; vector<eeee> to[200020]; void write(__int128_t x) { if(!x) { return ; } write(x / 10); cout << char(x % 10 + '0'); } int findfa(int x) { return f[x] == x? x : (f[x] = findfa(f[x])); } bool unionn(int x, int y) { x = findfa(x), y = findfa(y); f[y] = x; return x != y; } void kruskal() { for(int i = 1; i <= n; i++) { f[i] = i; } for(int i = 1; i <= m; i++) { if(unionn(arr[i].u, arr[i].v)) { to[arr[i].u].push_back({arr[i].v, arr[i].w}); to[arr[i].v].push_back({arr[i].u, arr[i].w}); } } } void DFS(int x = 1, int pa = 0) { fa[x][0] = pa; for(int i = 1; i <= 20; i++) { fa[x][i] = fa[fa[x][i - 1]][i - 1]; } for(auto i : to[x]) { if(i.v != pa) { dep[i.v] = dep[x] + i.w + t; ddp[i.v] = ddp[x] + 1; DFS(i.v, x); } } } int LCA(int x, int y) { if(ddp[x] < ddp[y]) { swap(x, y); } int tmp = ddp[x] - ddp[y]; for(int i = 20; i >= 0; i--) { if((tmp >> i) & 1) { x = fa[x][i]; } } if(x == y) { return x; } for(int i = 20; i >= 0; i--) { if(fa[x][i] != fa[y][i]) { x = fa[x][i], y = fa[y][i]; } } return fa[x][0]; } signed main() { freopen("run.in", "r", stdin); freopen("run.out", "w", stdout); cin >> n >> m; for(int i = 1; i <= m; i++) { cin >> arr[i].u >> arr[i].v >> arr[i].w; } sort(arr + 1, arr + m + 1, [](node a, node b) {return a.w < b.w;}); kruskal(); cin >> k >> t; DFS(); cin >> x; for(k--; k; k--) { cin >> y; int tmp = LCA(x, y); ans = ans + dep[x] + dep[y] - 2 * dep[tmp]; x = y; } //cout << cs << ' ' << cl << ' ' << pk << '\n'; if(ans) { ans = ans - t; } write(ans); return 0; }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析