[BZOJ 1106] [POI2007] 立方体大作战tet 【树状数组】
题目链接:BZOJ - 1106
题目分析
从1到2n枚举每一个位置。
如果枚举到某一个数,这个数已经是第二次出现,那么就看它和第一次出现的位置之间有多少数还没有被匹配,有多少没有匹配的就要进行多少次交换。
代码
#include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int MaxN = 100000 + 5; int n, Ans; int A[MaxN], T[MaxN], L[MaxN]; void Add(int x, int Num) { for (int i = x; i <= n; i += i & -i) T[i] += Num; } int Get(int x) { int ret = 0; for (int i = x; i; i -= i & -i) ret += T[i]; return ret; } int main() { scanf("%d", &n); n <<= 1; for (int i = 1; i <= n; ++i) scanf("%d", &A[i]); Ans = 0; for (int i = 1; i <= n; ++i) { if (L[A[i]] == 0) { L[A[i]] = i; Add(i, 1); } else { Ans += Get(i) - Get(L[A[i]]); Add(L[A[i]], -1); } } printf("%d\n", Ans); return 0; }