描述

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

题解

我们首先能大胆猜测,如果两个相同元素中间有一个在只出现一次的元素, 那么需要交换一次。

接下来我们只要求出每种元素的区间内有几个只出现一次的元素。

一次扫过$2 * n$个元素, 如果这种元素在之前没有出现过, 那么把该位置值记为 $1$

如果这种元素已经出现过, 那么把之前出现过的位置值记为-1, 当前位置值记为$1$

利用前缀和快速求出同种元素构成区间中的值的和, 并计入答案。

最后输出答案 $\div$ 2

利用树状数组可以查询前缀和, 单点修改。

代码

  1. #include<cstring>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #define rd read()
  5. using namespace std;
  6.  
  7. const int N = 1e6 + 1e5;
  8.  
  9. int l[N], sum[N], n;
  10.  
  11. int read() {
  12. int X = , p = ; char c = getchar();
  13. for(; c > '' || c < ''; c = getchar()) if(c == '-') p = -;
  14. for(; c >= '' && c <= ''; c = getchar()) X = X * + c - '';
  15. return X * p;
  16. }
  17.  
  18. int lowbit(int x) {
  19. return x & (-x);
  20. }
  21.  
  22. void add(int x, int d) {
  23. for(; x <= * n; x += lowbit(x)) sum[x] += d;
  24. }
  25.  
  26. int query(int x) {
  27. int re = ;
  28. for(; x; x -= lowbit(x)) re += sum[x];
  29. return re;
  30. }
  31.  
  32. int main()
  33. {
  34. n = rd;
  35. int ans = ;
  36. for(int i = ; i <= * n; ++i) {
  37. int x = rd;
  38. if(l[x]) {
  39. ans += query(i) - query(l[x]);
  40. add(l[x], -);
  41. add(i, );
  42. }
  43. else {
  44. add(i, );
  45. l[x] = i;
  46. }
  47. }
  48. printf("%d\n",ans >> );
  49. }

BZOJ1106[POI2007]立方体大作战tet - 树状数组的更多相关文章

  1. bzoj 1106 [POI2007]立方体大作战tet 树状数组优化

    [POI2007]立方体大作战tet Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 821  Solved: 601[Submit][Status][ ...

  2. BZOJ 1106: [POI2007]立方体大作战tet 树状数组 + 贪心

    Description 一个叫做立方体大作战的游戏风靡整个Byteotia.这个游戏的规则是相当复杂的,所以我们只介绍他的简单规 则:给定玩家一个有2n个元素的栈,元素一个叠一个地放置.这些元素拥有n ...

  3. BZOJ1106: [POI2007]立方体大作战tet

    1106: [POI2007]立方体大作战tet Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 419  Solved: 302[Submit][St ...

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

    1106: [POI2007]立方体大作战tet Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 682  Solved: 496[Submit][St ...

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

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1106 [题目大意] 给定玩家一个有2n个元素的栈,元素一个叠一个地放置. 这些元素拥有 ...

  6. [POI2007]立方体大作战tet

    题目 BZOJ 洛谷 做法 很巧妙的题,注意每种颜色只有两个 消除一种颜色,其实就是看中间有多少个没有被消除的块,这种动态距离问题显然能用树状数组解决 洛谷输出方案,暴力往下爬就行 My comple ...

  7. bzj1106: [POI2007]立方体大作战tet

    比较玄幻的题目. 考虑两个不同的元素 假设位置是 a...a...b...b... 那么不需要通过交换ab来消除ab,各自弄就行 若是 a...b...b...a... 那也没必要交换,先把b消掉就好 ...

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

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

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

    题意 给定一个长度为\(2n(1 \le n \le 500000)\)的序列,\(1\)~\(n\)各出现两次,可以交换相邻两项,两个同样的数放在一起会对消,求把所有数对消的最小交换次数. 分析 如 ...

随机推荐

  1. 学习MongoDB 四: MongoDB查询(一)

    一.简介 MongoDB提供了db.collection.find() 方法可以实现根据条件查询和指定使用投影运算符返回的字段省略此参数返回匹配文档中的所有字段. 二.db.collection.fi ...

  2. C关键字typedef及argc,argv,env参数含义

    C关键字typedef--为C中各种数据类型定义别名. 在此插一点C知识 int main(int argc,const char *argv[],const char *envp[])主函数的红色部 ...

  3. jsp 回车代替tab 自动切换text焦点

    方法一keyCode (IE11以后失效) <html> <head> <meta http-equiv="Content-Type" content ...

  4. Reactjs 打包后 Tomcat 部署 404问题

    配置web.xml <error-page> <error-code>404</error-code> <location>/index.html< ...

  5. MCI 录制指定格式音频

    可先用其他格式转换软件转换一段0秒指定格式的音频,然后用mcisendstring(L"open xxx.avi alias abc",0,0,0)打开,在进行录音mcisends ...

  6. Ubuntu下启动 Redis时, 提示 "Can't open the log file: Permission denied failed"

    问题来源:在删除var目录下的log文件时,将redis文件夹删除了.然后在重启时:/etc/init.d/redis-server start,提示: Starting redis-server: ...

  7. spring浏览器国际化的原理

    We will add two languages support to our application: English and German. Depending on the locale se ...

  8. C#中导出EXCEL服务器端不用安装OFFICE

    在实际开发过程中,有时候服务器端没安装OFFICE,你和服务器管理员去商量安装个OFFICE的时候,管理员很倔犟的不给你安装的时候,这个时候就可以考虑我这个方法是实现导出EXCEL了.如果你导出的EX ...

  9. mysql中binlog_format的三种模式

    mysql复制主要有三种方式:基于SQL语句的复制(statement-based replication, SBR),基于行的复制(row-based replication, RBR),混合模式复 ...

  10. Python 遍历文件夹 listdir walk 的区别

    一.一级目录import os path = 'd:\file'; for filename in os.listdir(path): print(os.path.join(path,filename ...