为何这样是错的(带注释、示意图)
查看原帖
为何这样是错的(带注释、示意图)
813622
Igallta楼主2024/11/26 17:07

首先,我在机房用了五台电脑进行对拍。数据生成器:

#include<bits/stdc++.h>
using namespace std;
int n;
mt19937 rnd(chrono::system_clock::now().time_since_epoch().count());
signed main(){
	freopen("I.in","w",stdout);
	n=rnd()%10000+80000;
	cout<<n<<'\n';
	for(int i=1;i<=n;i++){
		cout<<rnd()%20+1<<' ';
	}
	return 0;
}

然而他们现在都没有拍出来,令我气愤。

正文

我的思路是求出“区间”,“区间”开头就是自己的下标,末尾就是下一个和自己数字相同的值的下标。

如图所示:

用橙色线连的就是“区间”(实际上就只有那两个数)。

然后对终点进行排序,从小到大。

再记录一个 maxn,代表当前最大的终点的下标。

下一个区间的开始必须大于当前的 maxn。

如图所示:

(依次用、红、橙、黄、绿、蓝、深蓝,来代表下一次操作,粉色代表当前 ans)

这是代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 1;
int a[N], n, ans, frt[N];
bool b[N];
struct Node {
	int from, v;
} nxt[N];
signed main() {
//	freopen("I.in","r",stdin);
//	freopen("wrong.out","w",stdout);	
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		frt[a[i]] = 0x3f3f3f3f;
	}
	for (int i = n; i >= 1; i--) {//frt 记录区间终点
		nxt[i].v = frt[a[i]];
		nxt[i].from = i;
		frt[a[i]] = i;
	}
	sort(nxt + 1, nxt + 1 + n, [](Node x, Node y) {return x.v < y.v;});//通过区间最后一个点排序
	int maxn = 0;
	for (int i = 1; i <= n; i++) {
		if (nxt[i].v == 0x3f3f3f3f)break;//如果后面没了就 break
		if (nxt[i].from > maxn && !b[a[nxt[i].from]]) {//起点必须大于当前终点最大值
			ans += 2;//当前这个点和终点共两个
			b[a[nxt[i].from]] = 1;//记录这个值用过
			maxn = nxt[i].v;
		}
	}
	cout << ans;
	return 0;
}

求 hack 数据。

2024/11/26 17:07
加载中...