专栏文章
2025寒假专场6
题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqiq7cs
- 此快照首次捕获于
- 2025/12/04 05:27 3 个月前
- 此快照最后确认于
- 2025/12/04 05:27 3 个月前
入门模拟
入门模拟
扫描整个图中的
#,通过坐标最值可以找到矩形的边界,那么扫描矩形区域,出现.就是缺的地方了。一维区间询问,可以使用前缀和,考虑到给定的区间会把原来的睡眠时间分割开,使用二分找到第一个不小于区间端点的元素位置,修正分割量即可。
CPP#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long LL;
const int N = 4e5 + 10;
const int MOD = 1e9 + 7;
int a[N], s[N];
void solve() {
int n;
cin >> n;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
s[i] = s[i - 1] + (a[i] - a[i - 1]) * (i & 1);
}
int q;
cin >> q;
for (int i = 1; i <= q; ++i) {
int l, r;
cin >> l >> r;
int idl = lower_bound(a + 1, a + n + 1, l) - a;
int idr = lower_bound(a + 1, a + n + 1, r) - a;
LL cnt = 0;
if (idr & 1)
cnt += a[idr] - r;
if (idl & 1)
cnt += l - a[idl - 1];
cout << s[idr] - s[idl - 1] - cnt << endl;
}
}
signed main() {
int T = 1;
while (T--)
solve();
return 0;
}
从个点进行扩展,假设从点进行扩展,点的耐力值为,那么从扩展到邻接点时,的耐力值为, 只要耐力值不为,就可以继续扩展。
可能有多个点能扩展到点,那么对于点来说,应选择最大的耐力值,这样能解决接下来能尽可能多的扩展,且可以减少遍历的次数,降低时间复杂度。
利用优先队列代替普通队列进行;
CPP#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, m, k;
int h[N], p[N];
int vis[N], dis[N];
vector<int>g[N];
priority_queue< pair<int, int> > heap;
void bfs(){
while(heap.size()){
int step = heap.top().first, u = heap.top().second;
heap.pop();
if(vis[u]) continue;
vis[u] = 1;
if(step == 0) continue; // 扩不出去
for(auto v: g[u]){
if(vis[v]) continue;
heap.push({step - 1, v});
}
}
}
int main(){
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= m; i++){
int u, v;
scanf("%d%d", &u, &v);
g[u].push_back(v);
g[v].push_back(u);
}
for(int i = 1; i <= k; i++){
int h, p;
scanf("%d%d", &p, &h);
heap.push({h, p});
}
bfs();
int ans = 0;
for(int i = 1; i <= n; i++)
if(vis[i]) ans++;
printf("%d\n", ans);
for(int i = 1; i <= n; i++)
if(vis[i]) printf("%d ", i);
return 0;
}
能支持插入,自动排序,删除等操作的数据结构可以是,但是本题有重复元素,所以可以使用.
维护两个集合,第一个集合维护前K大数,第二个集合维护剩余的。
对于输入的,可以先判断在那个集合中,再维护集合大小,保证前大的数在第一个集合,若超过了,则移动到第二个集合中,若少了,则从第二个集合中移过来。
CPP#include<bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int n, k, q, a[N];
long long sum;
multiset<int>up, dn;
int main(){
scanf("%d%d%d", &n, &k, &q);
for(int i = 1; i <= k; i++)
up.insert(0);
for(int i = k + 1; i <= n; i++)
dn.insert(0);
while(q--){
int x, y;
scanf("%d%d", &x, &y);
auto it = up.find(a[x]);//
if(it != up.end()){
up.erase(it);
sum -= a[x];
}
else
dn.erase(dn.find(a[x]));
a[x] = y;
if(up.size() && y >= (*up.begin())){
up.insert(y);
sum += y;
}
else
dn.insert(y);
while(up.size() < k){
//auto it = (dn.end()--);
auto it = prev(dn.end());
up.insert(*it);
sum += (*it);
dn.erase(it);
}
while(up.size() > k){
auto it = up.begin();
sum -= (*it);
dn.insert(*it); // 插入值
up.erase(it);
}
printf("%lld\n", sum);
}
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...