POI2007TET-Tetris Attack

POI #Year2007 #贪心 #树状数组

考虑每一对数的最小代价为,将当前的换到最近的下面

用树状数组记录中间有几个没有被消掉的

// Author: xiaruize
const int N = 2e5 + 10;

int n, m;
int la[N];

struct BIT
{
	int tr[N];

	void add(int x, int v)
	{
		while (x <= m)
		{
			tr[x] += v;
			x += x & -x;
		}
	}

	int sum(int x)
	{
		int res = 0;
		while (x)
		{
			res += tr[x];
			x -= x & -x;
		}
		return res;
	}

	int get(int l, int r)
	{
		return sum(r) - sum(l - 1);
	}
} tr;
vector<int> vec;
void solve()
{
	cin >> n;
	int res = 0;
	m = n * 2;
	int cur = 0;
	rep(i, 1, m)
	{
		int x;
		cin >> x;
		if (!la[x])
		{
			tr.add(i, 1);
			la[x] = i;
			cur++;
			continue;
		}
		tr.add(la[x], -1);
		int tmp = tr.get(la[x], i);
		res += tmp;
		per(i, cur - 1, cur - tmp) vec.push_back(i);
		cur--;
	}
	cout << res << endl;
	for (auto v : vec)
		cout << v + 1 << endl;
}

#ifndef ONLINE_JUDGE
bool end_of_memory_use;
#endif

signed main()
{
	// freopen(".in","r",stdin);
	// freopen(".out","w",stdout);
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int testcase = 1;
	// cin >> testcase;
	while (testcase--)
		solve();
#ifndef ONLINE_JUDGE
	cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl;
	cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl;
#endif
	return 0;
}
posted @ 2024-04-15 19:41  xiaruize  阅读(4)  评论(0)    收藏  举报