给定玩家一个有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;
}