【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\n", ans);
return 0;
}
博客地址:www.cnblogs.com/iwtwiioi 本文为博主原创文章,未经博主允许不得转载。一经发现,必将追究法律责任。