bzoj1106 [POI2007]立方体大作战tet

Description

一个叫做立方体大作战的游戏风靡整个Byteotia。这个游戏的规则是相当复杂的,所以我们只介绍他的简单规则:给定玩家一个有2n个元素的栈,元素一个叠一个地放置。这些元素拥有n个不同的编号,每个编号正好有两个元素。玩家每次可以交换两个相邻的元素。如果在交换之后,两个相邻的元素编号相同,则将他们都从栈中移除,所有在他们上面的元素都会掉落下来并且可以导致连锁反应。玩家的目标是用最少的步数将方块全部消除。

Input

输入文件第一行包含一个正整数n(1<=n<=50000)。接下来2n行每行一个数ai,从上到下描述整个栈,保证每个数出现且仅只出现两次(1<=ai<=n)。初始时,没有两个相同元素相邻。并且保证所有数据都能在1000000步以内出解。

Output

输出文件第一行包含一个数m,表示最少的步数。

Sample Input

样例输入1
5
5
2
3
1
4
1
4
3
5
2
样例输入2
3
1
2
3
1
2
3

Sample Output

样例输出1
2
样例输出2
3

HINT

 

对于一个串,我们要把它的元素交换位置合并起来

对于合并,可以看成直接删除这两个元素,并且答案+=两者之间的距离

比如

直接从左往右读入,读到数字第一次出现的时候记录位置,第二次出现的时候直接和第一次合并掉。

这样的贪心证明是正确的:

1、假设有这样一个串12321,那么先合并两个2一定比先合并两个1更优

所以发现如果两对元素的位置是嵌套关系的话先删掉中间那对更优

2、假设又有123456712的串,要合并1、2,那么先合并1和先合并2是没有区别的

所以发现如果两对元素之间是有交集的话无论哪对先删都一样

3、显然如果两对元素之间没有交集的话肯定互不影响

综上,这样的贪心是正确的

最后只有用树状数组维护一下距离了

#include<cstdio>
#define LL long long
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x*f;
}
int n;
LL ans;
int c[100010];
int mrk[100010];
inline int lowbit(int x){return x&(-x);}
inline void add(int x,int d)
{
    for(int i=x;i<=2*n;i+=lowbit(i))
        c[i]+=d;
}
inline int query(int x)
{
    int s=0;
    for (int i=x;i;i-=lowbit(i))
        s+=c[i];
    return s;
}
int main()
{
    n=read();
    for (int i=1;i<=2*n;i++)
    {
        int x=read();
        if (mrk[x])
        {
            ans+=(LL)query(i-1)-query(mrk[x]);
            add(mrk[x],-1);
        }else
        {
            mrk[x]=i;
            add(i,1);
        }
    }
    printf("%lld\n",ans);
    return 0;
}

  

时间: 2024-12-19 16:33:03

bzoj1106 [POI2007]立方体大作战tet的相关文章

【BZOJ 1106】 [POI2007]立方体大作战tet

1106: [POI2007]立方体大作战tet Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 465  Solved: 336 [Submit][Status] Description 一个叫做立方体大作战的游戏风靡整个Byteotia.这个游戏的规则是相当复杂的,所以我们只介绍他的简单规则:给定玩家一个有2n个元素的栈,元素一个叠一个地放置.这些元素拥有n个不同的编号,每个编号正好有两个元素.玩家每次可以交换两个相邻的元素.如果在交换之后,

BZOJ 1106: [POI2007]立方体大作战tet

1106: [POI2007]立方体大作战tet Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 682  Solved: 496[Submit][Status][Discuss] Description 一个叫做立方体大作战的游戏风靡整个Byteotia.这个游戏的规则是相当复杂的,所以我们只介绍他的简单规则:给定玩家一个有2n个元素的栈,元素一个叠一个地放置.这些元素拥有n个不同的编号,每个编号正好有两个元素.玩家每次可以交换两个相邻的元素.如

bzoj1106([POI2007]立方体大作战tet)(树状数组)

传送门 首先要看出,对于每一对,其凑到一起所需要的操作次数是中间没被匹配的个数. 于是想到贪心,每次操作所需次数最小的. 但其实做法并不需要这么麻烦,只用从左到右扫一遍. 如果当前数字已经出现过,就统计其中未匹配的个数,同时把这一对标记为“已匹配”,就不会对后面的答案造成影响. 用树状数组维护即可,第一次出现树状数组中对应位置的权值+1,第二次出现时,累计答案,同时把前面相同的数的位置树状数组里权值-1. #include<bits/stdc++.h> #define LL long long

BZOJ 1106 [POI2007]立方体大作战tet(树状数组)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1106 [题目大意] 给定玩家一个有2n个元素的栈,元素一个叠一个地放置. 这些元素拥有n个不同的编号,每个编号正好有两个元素. 玩家每次可以交换两个相邻的元素.如果在交换之后,两个相邻的元素编号相同, 则将他们都从栈中移除,所有在他们上面的元素都会掉落下来并且可以导致连锁反应. 玩家的目标是用最少的步数将方块全部消除. [题解] 我们发现如果有一对可消除的方块在另一对中间,那么肯定是

BZOJ 1106 POI2007 立方体大作战tet 模拟

题目大意:给定一个长度为2n的序列,1~n各出现两次,可以交换相邻两项,两个同样的数放在一起会对消,求把所有数对消的最小交换次数 如果有一对在另一对中间 那么这一对肯定要先于另一对交换 除掉这个因素之外答案是确定的 由于保证交换次数<=100W,因此可以从左向右扫,维护一个栈,按顺序记录还没有被消掉的元素 如果新来的元素在栈里出现过,就直接去栈中查找,删除后直接维护就可以了 #include <cstdio> #include <cstring> #include <i

[BZOJ 1106] [POI2007] 立方体大作战tet 【树状数组】

题目链接:BZOJ - 1106 题目分析 从1到2n枚举每一个位置. 如果枚举到某一个数,这个数已经是第二次出现,那么就看它和第一次出现的位置之间有多少数还没有被匹配,有多少没有匹配的就要进行多少次交换. 代码 #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm>

BZOJ 1106 立方体大作战

BIT. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 200050 using namespace std; int n,t[maxn],x,pos[maxn],ans=0; int lowbit(int x) { return (x&(-x)); } int query(int x) { int ret=0; for (

poi2007

序:为什么写poi,zy说poi都是思路题目,不像hnoi妈的数据结构队..... 1.bzoj1102 题目大意:定义了一个山谷和山峰,求他们数量. 题解:这种题bfs咯,在bfs的时候记录一下相邻的比我大的有多少,比我小的有多少,然后更新答案: 代码: 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cmath&

bzoj1106 树状数组

https://www.lydsy.com/JudgeOnline/problem.php?id=1106 一个叫做立方体大作战的游戏风靡整个Byteotia.这个游戏的规则是相当复杂的,所以我们只介绍他的简单规 则:给定玩家一个有2n个元素的栈,元素一个叠一个地放置.这些元素拥有n个不同的编号,每个编号正好有两个 元素.玩家每次可以交换两个相邻的元素.如果在交换之后,两个相邻的元素编号相同,则将他们都从栈中移除, 所有在他们上面的元素都会掉落下来并且可以导致连锁反应.玩家的目标是用最少的步数将