2018 計蒜之道 初賽 第一場
阿新 • • 發佈:2018-05-13
得到 ret ++ pair bsp 連通 所有 sizeof -i
百度無人車
二分答案即可。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) #define MP make_pair #define fi first #define se second typedef long long LL; int n; LL a[100010]; LL p, s; LL ss = 0; LL l, r; int main(){ scanf("%d", &n); LL mx = 0; rep(i, 1, n) scanf("%lld", a + i), mx = max(mx, a[i]), ss += a[i]; scanf("%lld%lld", &p, &s); LL x = s / p; l = 1, r = mx; while (l + 1 < r){ LL mid = (l + r) / 2; LL now = 0; rep(i, 1, n) now += min(a[i], mid); if (ss - now <= x) r = mid; else l = mid + 1; } LL now = 0; rep(i, 1, n) now += min(a[i], l); if (ss - now <= x) printf("%lld\n", l); else printf("%lld\n", r); return 0; }
百度科學家(簡單)
直接模擬
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) #define MP make_pair #define fi first #define se second typedef long long LL; const int N = 2e2 + 5; LL a[N]; LL y; LL ans = 1e18; bool mp[N][N]; bool v[N]; int n, m, op, x, l, r; int pos[N], et; LL calc(int x){ v[x] = true; LL ans = a[x]; rep(i, 1, et - 1){ if (!v[i] && mp[x][i]) ans += calc(i); } return ans; } int main(){ scanf("%d", &n); rep(i, 1, n){ scanf("%lld", &a[i]); pos[i] = i; } et = n + 1; scanf("%d", &m); while (m--){ scanf("%d", &op); if (op == 0) { scanf("%d%lld", &x, &y); pos[x] = et; a[et++] = y; } else{ scanf("%d%d%d", &x, &l, &r); rep(j, l, r) mp[pos[x]][pos[j]] = true; } } rep(i, 1, et - 1){ memset(v, 0, sizeof v); ans = min(ans, calc(i)); } printf("%lld\n", ans); return 0; }
百度科學家(中等)
$∑r-l+1 <= 10^{5}$,根據這個很容易得到這是一個有向圖的模型。
tarjan縮點,找出每個強連通分量的權值和,找到所有出度為0的強連通分量,找一個權值和最小的。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) #define MP make_pair #define fi first #define se second typedef long long LL; const int N = 1e5 + 10; LL a[N], c[N]; LL y; LL ans = 1e18; vector <int> mp[N]; stack <int> stk; int pos[N]; int low[N], belong[N], dfn[N]; int cnt, ti; int n, m, op, x, l, r; int et; bool vis[N], out[N]; void tarjan(int x, int fa) { ti++; dfn[x] = low[x] = ti; vis[x] = true; stk.push(x); for (auto y : mp[x]) { if (dfn[y] == 0) { tarjan(y, x); low[x] = min(low[x], low[y]); } else if (vis[y]) { low[x] = min(low[x], dfn[y]); } } if (dfn[x] == low[x]) { int y; cnt++; do{ y = stk.top(); stk.pop(); vis[y] = false; belong[y] = cnt; c[cnt] += a[y]; } while (x != y); } } void solve(int n){ memset(dfn, 0, sizeof dfn); memset(vis, 0, sizeof vis); cnt = ti = 0; rep(i, 1, n) if (!dfn[i]) tarjan(i, 0); } int main(){ scanf("%d", &n); rep(i, 1, n){ scanf("%lld", &a[i]); pos[i] = i; } et = n + 1; scanf("%d", &m); rep(i, 1, m){ scanf("%d", &op); if (op == 0){ scanf("%d%lld", &x, &y); pos[x] = et; a[et++] = y; } else{ scanf("%d%d%d", &x, &l, &r); rep(j, l, r) mp[pos[x]].push_back(pos[j]); } } solve(et - 1); memset(out, 0, sizeof out); rep(i, 1, et - 1){ for (auto z : mp[i]){ if (belong[i] != belong[z]) out[belong[i]] = true; } } rep(i, 1, cnt) if (!out[i]) ans = min(ans, c[i]); printf("%lld\n", ans); return 0; }
百度科學家(困難)
留坑。
2018 計蒜之道 初賽 第一場