首页 > 技术文章 > [BZOJ 1106] [POI2007] 立方体大作战tet 【树状数组】

JoeFan 2015-03-09 20:29 原文

题目链接: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;
}

  

推荐阅读