zoukankan      html  css  js  c++  java
  • 【基本操作】主席数统计区间不同颜色个数

    例题:询问 $n$ 个数中无修改的区间不同数个数,不带修改(SPOJ的一道题)。

    方法1:直接删

    我们尝试头铁地开正常的下标主席树!

    依次插入 $n$ 个数,插入第 $i$ 个数时,我们只要在把第 $i$ 个版本的主席树的第 $i$ 位 $+1$ 就可以了,表示多出一个数。

    但前面与它相同的数怎么处理?

    可以记录每个数上一次出现的位置,在当前版本的主席树中,给当前位 $+1$ 后,把上一次出现相同数的位置 $-1$,这样就不会被算重复了。

    如果数过大,离散化一下就好了。

    然后对于 $[left,right]$ 这样的区间询问,在第 $right$ 个版本的线段树上查询 $[left,right]$ 的和即可。

    方法2:考虑差分思想。

    如果我们保守,就换用权值主席树。

    做过 $APIO 2018space T1$ (的我)即可了解这种思路(那道题让你用判断一个区间内是否包含所有颜色,做法有些类似)。

    就是你直接把主席树第 $i$ 个位置的权值 $pre$ 设为这位的数上一次出现的位置。然后查询一个区间 $[l,r]$ 的颜色数 其实就是查询区间 $[1,r]$ 有多少个 $pre$ 值 $lt l$(直接查 $[1,r]$ 是为了方便,答案不变,但不用再写个数据结构维护)。

    重点就是动态查询前缀中 有多少个数 小于一个给定数,每次在主席树的第 $r$ 个版本上查权值主席树中 有多少个数小于 $l$ 就完事了。

    这两个做法都可以直接改成朴素线段树模拟+离线回答询问(每达到一个右端点就回答询问)。也就是说这里强行转化成主席树讲。

     

    例题:一棵树,每个点都有一种颜色,每次询问以一个点为根的子树中的不同颜色数。

    用 $dfs$ 序建主席树的版本 及 使用主席树的下标,然后只能用上例的方法2维护(一个点要从它的父亲的版本转移过来,定义一个数上一次出现的位置为 它在当前点的祖先中与这个数相等且离这个数所在点最近的点),查询子树 转为 查询子树对应的 $dfs$ 序区间 即可。

  • 相关阅读:
    字符串指针与字符数组的区别
    为什么stc15的单片机,运行了几秒后就蹦了
    判断一个数是否是2的整数次幂
    Ubuntu下使用gcc编译c文件,未识别cos,sin
    数字图像基本处理算法
    开发板启动时,内核打印出"can't access tty,job control turned off"
    c语言里如何调用汇编里的变量?
    leetcode516 Longest Palindromic Subsequence
    leetcode523 Continuous Subarray Sum
    leetcode650 2 Keys Keyboard
  • 原文地址:https://www.cnblogs.com/scx2015noip-as-php/p/10003795.html
Copyright © 2011-2022 走看看