1242. 修改数组

摘要
Title: 1242. 修改数组
Tag: 并查集、树状数组、二分
Memory Limit: 64 MB
Time Limit: 1000 ms

Powered by:NEFU AB-IN

Link

1242. 修改数组

  • 题意

    见原题

  • 思路

    • 并查集单链表用法
      将前面枚举过的元素用一个集合来表示,集合的根元素是集合所有元素的最大值
      1242
    • 树状数组+二分
      可以观察到,定义f(x)f(x)函数,为该数减去前面被标记的数,f(x)=xs[x]f(x) = x - s[x]的值是单调递增
      我们需要找出最靠左的,且严格大于f(x)f(x)的数
      比如 现在是2, 4被标记了,那么f(x)f(x)的状态为:

      x:1,2,3,4,5,6,7,8f:1,1,2,2,3,4,5,6x: 1, 2, 3, 4, 5, 6, 7, 8 \\ f: 1, 1, 2, 2, 3, 4, 5 ,6

      如果此时问2,而2已经被标记了,那么就找严格大于f(21)f(2-1)的数,即3
  • 代码

    并查集

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    '''
    Author: NEFU AB-IN
    Date: 2022-04-05 16:45:40
    FilePath: \ACM\Acwing\1242.py
    LastEditTime: 2022-04-05 16:45:40
    '''
    import sys

    sys.setrecursionlimit(int(2e9))

    N = int(1e6 + 10)
    fa = [i for i in range(N)]


    def find(x):
    if x != fa[x]:
    fa[x] = find(fa[x])
    return fa[x]


    n = int(input())
    a = list(map(int, input().split()))

    for i in range(n):
    x = find(a[i])
    a[i] = x
    fa[x] = x + 1

    for i in a:
    print(i, end=" ")

    树状数组+二分

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    '''
    Author: NEFU AB-IN
    Date: 2022-04-05 18:21:40
    FilePath: \ACM\Acwing\1242.1.py
    LastEditTime: 2022-04-05 18:37:26
    '''
    N = int(1e6 + 10)
    Matrix = lambda: [0] * N
    lowbit = lambda x: x & -x
    tr, a = Matrix(), Matrix()


    def add(x, d):
    i = x
    while i < N:
    tr[i] += d
    i += lowbit(i)


    def query(x):
    i, ans = x, 0
    while i:
    ans += tr[i]
    i -= lowbit(i)
    return ans


    def check(l, r):
    return r - query(r) > (l - 1) - query(l - 1)


    n = int(input())
    a = list(map(int, input().split()))
    a = [0, *a]

    for i in range(1, n + 1):
    l, r = a[i], N
    while l < r:
    mid = l + r >> 1
    if check(a[i], mid):
    r = mid
    else:
    l = mid + 1
    print(r, end=" ")
    add(r, 1)
使用搜索:谷歌必应百度