AtCoder Beginner Contest 305
D - Sleep Log
原题链接
题面
思路
前缀和+二分
代码
void solve(){
int n; cin >> n;
vector<int> v(n + 10);
vector<ll> f(n + 10);
for(int i = 1; i <= n; i++) {
cin >> v[i];
if(i & 1) f[i] = f[i - 1] + v[i] - v[i - 1];
else f[i] = f[i - 1];
}
int q; cin >> q;
while(q --) {
int l, r; cin >> l >> r;
ll ans = 0;
int sl = lower_bound(v.begin() + 1, v.begin() + n + 1, l) - v.begin();
int sr = lower_bound(v.begin() + 1, v.begin() + n + 1, r) - v.begin();
ans += f[sr] - f[sl];
if(sl % 2) {
ans += v[sl] - l;
}
if(sr % 2) {
ans -= v[sr] - r;
}
cout << ans << '\n';
}
}
E - Art Gallery on Graph
原题链接
题面
思路
- 堆优化dijkstra,不过权值是按照最大的先来,因为如果按照最大的先来,一个点被遍历到时此点剩余的权值也是最大的,而后续再遍历到此点时权值一定比第一次遍历到小。
代码
const int N = 2e5+10;
vector<int> g[N];
vector<int> d(N);
void solve(){
int n, m, k; cin >> n >> m >> k;
for(int i = 1; i <= m; i++) {
int u, v; cin >> u >> v;
g[u].push_back(v), g[v].push_back(u);
}
set<int> ans;
function<void()> dijk = [&]() {
priority_queue<pii> pq;
for(int i = 1; i <= k; i++) {
int p, h; cin >> p >> h;
pq.push({h, p});
d[p] = h;
}
while(pq.size()) {
auto u = pq.top().second, w = pq.top().first; pq.pop();
if(ans.count(u)) continue;
ans.insert(u);
for(auto& v:g[u]) {
d[v] = max(d[v], w - 1);
if(ans.count(v)) continue;
if(d[v] > 0 || w > 0)
pq.push({d[v], v});
}
}
};
dijk();
cout << ans.size() << '\n';
for(auto& i:ans) cout << i << ' ';
cout << '\n';
}
F - Dungeon Explore
原题链接
题面
思路
代码
待补