zoukankan      html  css  js  c++  java
  • 洛谷 P1972"[SDOI2009]HH的项链"(离线+树状数组 or 在线+主席树)

    传送门

    •题意

      给你一个包含 n 个数的数组 $a$;

      有 m 此操作,每次操作求区间 [l,r] 中不同数的个数;

    •题解(离线+树状数组)

      以样例 $[1,2,3,4,3,5]$ 为例,求解区间 $[2,6]$ 的不同数的个数;

      按照模拟思路,肯定是从后往前查找不同数的个数;

      从 $6$  开始,向前查找的结果为:$[5,3,4,2]$ 共四个数;

      你会发现 3 在区间 $[2,6]$ 出现了两次,但是,只需要距右端点 $6$ 最近的那个 3;

      也就是说,对于多个区间询问,我们可以将这些询问按照右端点(r)排序;

      对于处理到的区间 $[l_i,r_i]$,如果当前处理的数 $val$ 在之前出现过;

      那么,按照优先靠近右端点的思想,将之前出现的 $val$ 的位置从树状数组中减去;

      将当前的 $val$ 的位置加入到树状数组中;

      判断当前位置的 $val$ 是否出现过及最靠近当前位置的 $val$,用个数组 $last$ 存储 $val$ 在 [1,当前位置-1] 中最后出现的位置即可;

      查询的话,树状数组中 $Sum(r_i)$ 指的是 $[1,r_i]$ 中靠近右端点且不重复的数的个数;

      那么,当前区间的答案就为 $Sum(r_i)-Sum(l_i-1)$;

    •Code

      离线树状数组查询区间多少个不同的数.cpp

      莫名bug:

        将第 52~53 行代码合并成 last[a[index]]=index++;

        就 WA 了;

      疑惑解决:

        int index = 1;

        a[index]=index++;

        上述语句,我所期待的结果是 a[1]=1 , index=2;

        但实际是 a[2]=1 , index=2;

        也就是说,在 a 调用 index 时已经将 index++ 了,而右边等这个语句全部结束后才++;

        即 a 用的是 2 赋值为 1 后, index=index+1;

        也就是输出结果 a[2]=1 , index=2;

    •题解(在线+主席树)

      要用主席树的话,首先得明确每棵树要维护什么;

      上述题解,得到了一个结论,对于询问的区间 $[l,r]$,$[1,r]$ 中重复的数要优先考虑靠近 r 的那个;

      这样的话,我们就可以用主席树维护 $[1,r]$ 中不重复的数的个数;

      及 $rt_1,rt_2,cdots ,rt_n$ 这 n 可树分别维护 $[1,1],[1,2],cdots ,[1,n]$ 中不重复数的个数;

      假设当前需要处理第 r 个数,及需要构造的第 r 棵树;

      对于即将插入主席树中的数 $a_r$,先判断一下 $a_r$ 在此之前是否出现过,并且要确定之前出现过的距 $r$ 最近的位置;

      这个也很好找,直接用 $last$ 数组就行;

      维护的话,如果 $val$ 在之前出现过,就将其距 $r$ 最近的位置记录的值删掉,加入到当前的位置 $r$;

      对于区间 $[l,r]$ 查询的话,直接在 $rt_r$ 这颗树上查找相应区间 $[l,r]$ 中不重复数的个数即可,线段树的常规操作;  

      (PS:这道题目的数据加强了,在线主席树是会 TLE 的,只能选择离线做法,我做这道题的目的是复习一下主席树,想 AC 的话,去这儿

    •Code

      在线主席树查询区间多少个不同的数.cpp

  • 相关阅读:
    1012 The Best Rank (25 分)(排序)
    1011. World Cup Betting (20)(查找元素)
    1009 Product of Polynomials (25 分)(模拟)
    1008 Elevator (20 分)(数学问题)
    1006 Sign In and Sign Out (25 分)(查找元素)
    1005 Spell It Right (20 分)(字符串处理)
    Kafka Connect 出现ERROR Failed to flush WorkerSourceTask{id=local-file-source-0}, timed out while wait
    flume、kafka、avro组成的消息系统
    Java23种设计模式总结【转载】
    Java编程 思维导图
  • 原文地址:https://www.cnblogs.com/violet-acmer/p/11573112.html
Copyright © 2011-2022 走看看