【BZOJ】1106: [POI2007]立方体大作战tet

题意

给定一个长度为(2n(1 le n le 500000))的序列,(1)~(n)各出现两次,可以交换相邻两项,两个同样的数放在一起会对消,求把所有数对消的最小交换次数。

分析

如果有一对在另一对之间,则这一对肯定要在另一对前面消除。
否则答案不变。

题解

维护一个栈存储第一次出现的数,然后如果新进来的元素已经出现过,则暴力找出来统计答案。

#include <bits/stdc++.h>
using namespace std;
inline int getint() {
	int x=0, c=getchar();
	for(; c<48||c>57; c=getchar());
	for(; c>47&&c<58; x=x*10+c-48, c=getchar());
	return x;
}
int s[50005], vis[50005], top;
int main() {
	int n=getint(), ans=0;
	for(int i=1, nn=n<<1; i<=nn; ++i) {
		int a=getint();
		if(vis[a]) {
			for(int j=vis[a]; j!=top; swap(s[j], s[j+1]), vis[s[j]]=j, ++j, ++ans);
			--top;
		}
		else {
			s[vis[a]=++top]=a;
		}
	}
	printf("%d
", ans);
	return 0;
}
原文地址:https://www.cnblogs.com/iwtwiioi/p/4985639.html