社区讨论

55pts求助边界处理问题

P3620[APIO/CTSC2007] 数据备份参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@lo86z9mh
此快照首次捕获于
2023/10/27 13:47
2 年前
此快照最后确认于
2023/10/27 13:47
2 年前
查看原帖
感觉这题错在边界处理没做好,但又不知道哪里错了
CPP
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#define ll long long
using namespace std;
ll n, m, a[1000006], now;
bool bo[1000006];
struct node {
	ll v, pre, next;//pre是上一条边的编号,next是下一条边的编号
}dis[1000006];//dis表示边
priority_queue< pair< ll, ll > >dui;
bool cmp(node aa, node bb) {
	return aa.v < bb.v;
}
int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	dis[0].v = dis[1].v = 66666666666, dis[1].next = 2;
	for (int i = 2; i <= n; i++) {//边从2开始编号,因为第一条边非法
		dis[i].v = a[i] - a[i - 1];
		dui.push(make_pair(-dis[i].v, i));
		dis[i].pre = i - 1, dis[i].next = i + 1;
	}
	ll ans = 0, sum = 0;
	now = n;//反悔边增加空间存
	while (m--) {
		sum = 0;
		ll x = dui.top().second;
		dui.pop();
		while (bo[x]) {//该边不合法,舍弃
			x = dui.top().second;
			dui.pop();
		}
		bo[dis[x].pre] = bo[dis[x].next] = 1;
		ans += dis[x].v;
		if (x!=2 && x!= n) {//不是第一条或者最后一条边
			sum = dis[dis[x].pre].v + dis[dis[x].next].v - dis[x].v;
			dis[++now].v = sum, dis[now].pre = dis[dis[x].pre].pre, dis[now].next = dis[dis[x].next].next;
			dis[dis[dis[x].pre].pre].next = now, dis[dis[dis[x].next].next].pre = now;
		}
		else if (dis[x].pre == 2) {//是第一条边
			sum = dis[dis[x].next].v - dis[x].v;
			dis[++now].v = sum, dis[now].pre = dis[x].pre, dis[now].next = dis[dis[x].next].next;
			dis[dis[dis[x].next].next].pre = now;
		}
		else {//是最后一条边
			sum = dis[dis[x].pre].v - dis[x].v;
			dis[++now].v = sum, dis[now].pre = dis[dis[x].pre].pre, dis[now].next = dis[x].next;
			dis[dis[dis[x].pre].pre].next = now;
		}
		dui.push(make_pair(-sum,now));
	}
	cout << ans << endl;
}

回复

0 条回复,欢迎继续交流。

正在加载回复...