R257983 2023-03-02 21:24 采纳率: 20%
浏览 19

C++蓝桥杯改变数组元素问题差分算法


#include <iostream>     
#include <cstring>
 
using namespace std;

const int N=200010;

int n;
int b[N];

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        memset(b,0,(n+1)*4);
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            x=min(x,i);
            int l=i-x+1,r=i;
            b[l]++,b[r+1]--;
        }
        for(int i=1;i<=n;i++)
            b[i]+=b[i-1];
        for(int i=1;i<=n;i++)
            printf("%d ",!!b[i]);
        puts("");
    }
    return 0;
}

b[l]++,b[r+1]--;如何解释,不是把l和r之间的+1吗?
b[i]+=b[i-1];又怎么解释?

  • 写回答

3条回答 默认 最新

  • CodeBytes 2023-03-02 21:37
    关注

    该回答引用ChatGPT

    $a_1,a_2,\cdots,a_n$,对于每个位置 $i$,求出该位置之前的所有数中,最大值不超过 $i$ 的数的个数。

    代码中使用的是差分的思想。具体来说,对于每个数 $a_i$,我们将它和位置 $i$ 取 $\min$,记为 $x$,则 $a_i$ 之前的数中最大值不超过 $i$ 的数的个数就是 $i-x+1$。于是我们将差分数组 $b$ 的第 $l$ 项加 $1$,第 $r+1$ 项减 $1$,其中 $l=i-x+1,r=i$。这样得到的差分数组 $b$ 的前缀和就是我们要求的结果。具体来说,对于每个位置 $i$,$b_i$ 表示有多少个数的最大值不超过 $i$。对 $b$ 数组求前缀和后,$b_i$ 表示有多少个数的最大值不超过 $i$,将其输出即可。

    至于你的疑问:

    b[l]++,b[r+1]-- 是在对差分数组进行修改。我们将 $[l,r]$ 这个区间内的数的贡献加上 $1$,也就是说,$[l,r]$ 这个区间内的所有位置的值都加 $1$,同时,将 $r+1$ 这个位置的值减 $1$,这样可以保证下一次处理 $[l',r']$ 区间时不会把 $[l,r]$ 的贡献算进去。
    b[i]+=b[i-1] 是在对差分数组求前缀和,也就是将差分数组还原为原数组。具体来说,$b_i$ 表示了原数组中最大值不超过 $i$ 的数的个数,所以将 $b$ 数组求前缀和后,$b_i$ 表示的就是原数组中最大值不超过 $i$ 的数的个数。

    评论

报告相同问题?

问题事件

  • 创建了问题 3月2日

悬赏问题

  • ¥15 matlab数据降噪处理,提高数据的可信度,确保峰值信号的不损失?
  • ¥15 怎么看我在bios每次修改的日志
  • ¥15 python+mysql图书管理系统
  • ¥15 Questasim Error: (vcom-13)
  • ¥15 船舶旋回实验matlab
  • ¥30 SQL 数组,游标,递归覆盖原值
  • ¥15 为什么我的数据接收的那么慢呀有没有完整的 hal 库并 代码呀有的话能不能发我一份并且我用 printf 函数显示处理之后的数据,用 debug 就不能运行了呢
  • ¥20 gitlab 中文路径,无法下载
  • ¥15 用动态规划算法均分纸牌
  • ¥30 udp socket,bind 0.0.0.0 ,如何自动选取用户访问的服务器IP来回复数据