其他分享
首页 > 其他分享> > 差分数组 快速处理区间加减操作

差分数组 快速处理区间加减操作

作者:互联网

第一行n和m(都是100以内) 接下来n行 每行两个1-m的数 代表区间[l, r]
输出没有被任何区间覆盖到的整数们(第一行输出个数)

题目链接

示例:每次输入区间[l,r]打标记——对数组下标[l,r]的值均执行+1操作

for i in range(n):
    l,r=input().split()
    l,r=int(l),int(r)
    arr[l]+=1;
    arr[r+1]-=1;
    # 数组[l,r]区间+1

若干次操作以后

#若干次操作后数组的样子
for i in range(1,m+2):
    brr[i] = brr[i-1] + arr[i]

寻找没有被标记过的整数——数组中没有被标记过的元素 ——寻找值为0的元素


ans = [i+1 for i,x in enumerate(brr[1:m+1]) if x==0]

完整Accepted代码:

n,m=input().split()
n,m=int(n),int(m)
arr,brr=[0]*(m+2),[0]*(m+2) #指定大小和初值的list

for i in range(n):
    l,r=input().split()
    l,r=int(l),int(r)
    arr[l]+=1;
    arr[r+1]-=1;
    # 数组[l,r]区间+1
#若干次操作后数组的样子
for i in range(1,m+2):
    brr[i] = brr[i-1] + arr[i]



ans = [i+1 for i,x in enumerate(brr[1:m+1]) if x==0]

print(len(ans))

for num in ans:
    print(num,end=" ")

差分思想的定义、用途:
1.定义: 对于已知有n个元素的离线数列d,我们可以建立记录它每项与前一项差值的差分数组f:显然,f[1]=d[1]-0=d[1];对于整数i∈[2,n],我们让f[i]=d[i]-d[i-1]。
2.简单性质: (1)计算数列各项的值:观察d[2]=f[1]+f[2]=d[1]+d[2]-d[1]=d[2]可知,数列第i项的值是可以用差分数组的前i项的和计算的,即d[i]=f[i]的前缀和。
(2)计算数列每一项的前缀和:第i项的前缀和即为数列前i项的和,那么推导可知
在这里插入图片描述
即可用差分数组求出数列前缀和;
3.用途: (1)快速处理区间加减操作: 假如现在对数列中区间[L,R]上的数加上x,我们通过性质(1)知道,第一个受影响的差分数组中的元素为f[L],即令f[L]+=x,那么后面数列元素在计算过程中都会加上x;最后一个受影响的差分数组中的元素为f[R],所以令f[R+1]-=x,即可保证不会影响到R以后数列元素的计算。这样我们不必对区间内每一个数进行处理,只需处理两个差分后的数即可;
(2)询问区间和问题:
由性质(2)我们可以计算出数列各项的前缀和数组sum各项的值;那么显然,区间[L,R]的和即为ans=sum[R]-sum[L-1];

参考博客

标签:arr,数列,brr,差分,加减,数组,区间
来源: https://blog.csdn.net/weixin_56336619/article/details/115528331