BZOJ1106 [POI2007]立方體大作戰tet 樹狀數組

給定玩家一個有2n個元素的棧,元素一個疊一個地放置。這些元素擁有n個不同的編號,每個編號正好有兩個
元素。玩家每次可以交換兩個相鄰的元素。如果在交換之後,兩個相鄰的元素編號相同,則將他們都從棧中移除,

所有在他們上面的元素都會掉落下來並且可以導致連鎖反應。玩家的目標是用最少的步數將方塊全部消除。

碰到像1212這樣的肯定要交換一次

所以記錄一下未消除的數字個數,以及出現過的數字的位置

當每個數第二次出現的時候,答案就增加這兩個位置之間剩餘數字的個數.

這個用樹狀數組維護

#include<bits/stdc++.h>
#define LL long long
#define clr(x,i) memset(x,i,sizeof(x))
#define lowbit(x) (x&(-x))
using namespace std;
const int N=200005;
int n,x,c[N],pos[N],cnt,ans;
void change(int x,int v)
{
	while(x<=n){
		c[x]+=v;x+=lowbit(x);
	}
}
int query(int x)
{
	int ret=0;
	while(x>0){
		ret+=c[x];x-=lowbit(x);
	}
	return ret;
} 
int main()
{
	scanf("%d",&n);
	n*=2;
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&x);
		if(!pos[x]){
			pos[x]=i;cnt++;
			change(pos[x],1);
		}
		else{
			ans+=cnt-query(pos[x]);
			change(pos[x],-1);
			cnt--;
		}
	}
	printf("%d",ans);
	return 0;
}
 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章