观察到n很小,可以使用一个二维数组f[i][j]代表i是否出现在过位置j.
然后每次移动数组时,直接模拟这个过程。然后用数组[l,n]这一段更新即可。
# 读取输入的 n 和 q,分别表示数组大小和查询次数
n, q = map(int, input().split())
# 初始化数组 a,存储 1 到 n 的元素
a = [i for i in range(n + 1)]
# 创建一个二维布尔数组 f,f[i][j] 表示 i 是否出现在位置 j
f = [[False] * (n + 1) for _ in range(n + 1)]
# 初始化对角线,表示每个数 i 在位置 i 出现
for i in range(1, n + 1):
    f[i][i] = True
# 临时数组 b 用于存储移动过程中需要的值
b = [0] * (n + 1)
# 处理每个查询
for _ in range(q):
    # 读取查询的左右边界 l 和 r
    l, r = map(int, input().split())
    # 将 a[l:r+1] 的值复制到临时数组 b
    for i in range(l, r + 1):
        b[i] = a[i]
    j = l  # j 用于追踪新数组 a 的写入位置
    # 将 a[r+1:n] 的元素移动到 a[l:n]
    for i in range(r + 1, n + 1):
        a[j] = a[i]
        j += 1
    
    # 将临时数组 b 的元素从 l 开始写入 a
    for i in range(l, n + 1):
        a[j] = b[i]
        j += 1
        if j > n:  # 如果超出数组范围,停止写入
            break
    
    # 更新布尔数组 f,记录新的位置关系
    for i in range(l, n + 1):
        f[a[i]][i] = True
# 计算结果
result = []
for i in range(1, n + 1):
    # 对于每个 i,统计它在所有位置 j 的出现次数
    ans = sum(f[i][j] for j in range(1, n + 1))
    result.append(str(ans))
# 输出结果
print(" ".join(result))
OJ会员可以通过点击题目上方《已通过》查看其他通过代码来学习。
一个长度为n的数组A1,A2,...,An,其中Ai=i。q次操作,每次选择区间[l,r]将下标从l r的数全部取出,
按原顺序放置到数列末尾,数组变成
$A_1,A_2,...,A_{l-1},A_{l+1},A_{r+2},...,A_n,A_l,A_{i+1},...,A_r$
例如,[1,2,3,4,5,6]第1次选择操作[2,4],变化后数列变为[1,5,6,2,3,4],第2次选择操作[3,5],数列变为[1,5,4,6,2,3]。请输出q次操作过程中,数字i出现过的下标位置的个数。
第一行包含两个整数n q (1≤n,q≤3×103),表示数列的长度和操作次数。
接下来q行,每行包含两个整数l,r(1≤l≤r≤n),表示q次操作。
输出一行包含n个整数,第i个数表示数字i出现过的下标位置的个数。
注意:python请选择编译器pypy3提交,否则可能运行超时!!!
输入
6 2
1 3
2 4
输出
3 2 2 2 3 3
说明
[1,2,3,4,5,6],第1次选择操作[1,3],变化后数列变为[4,5,6,1,2,3],第2次选择操作[2,4],数列变为 [4.2,3,5,6,1]。 数字1操作过程中出现的下标分别为[1,4,6],共3个。 数字2操作过程中出现的下标分别[2,5,2],共2个。 数字3操作过程中出现的下标分别[3,6,3],共2个。 数字4操作过程中出现的下标分别[4,1,1],共2个。 数字5操作过程中出现的下标分别[5,2,4],共3个。 数字6操作过程中出现的下标分别[6,3,5],共3个。
输入
20 6
1 5
8 12
6 18
3 9
5 5
13 20
输出
6 6 6 6 6 2 2 4 4 4 5 5 6 6 6 5 5 5 5 5