• 一维和二维差分


    前缀和的逆运算

    一维差分

    a1,a2,a3……an  //前缀和数组

    构造b1,b2,b3……bn    b数组是a数组的差分

    使得ai=b1+b2+……+bi

    故b1=a1;

    b2=a2-a1;

    b3=a3-a2

    bn=an-a(n-1)

    当然,实际构造中不需要特意构造b,具体操作参考代码部分

    可认为a数组初始全为0,然后进行[1,1]+a1,[2,2]+a2,[3,3]+a3……[n,n]+an的借助b数组的插入操作

    作用:当需要希望a数组[l,r]全部加c时,时间复杂度为O(n);

              可使bl+c,b(r+1)-c达到同样效果,时间复杂度为O(1);

    输入一个长度为 n 的整数序列。

    接下来输入 m个操作,每个操作包含三个整数 l,r,c表示将序列中 [l,r] 之间的每个数加上 c。

    请你输出进行完所有操作后的序列。

    1. #include
    2. #include
    3. using namespace std;
    4. const int N = 1e6;
    5. int a[N]={0}, b[N] = {0};
    6. void insert(int l,int r,int b[], int c)
    7. {
    8. b[l] += c;
    9. b[r+1] -= c;
    10. }
    11. int main()
    12. {
    13. int n, m;
    14. cin >> n >> m;
    15. for (int i = 1; i <= n; i++)
    16. {
    17. cin >> a[i];
    18. insert(i, i, b, a[i]);
    19. }
    20. while (m--)
    21. {
    22. int l, r, c;
    23. cin >> l >> r >> c;
    24. insert(l, r, b, c);
    25. }
    26. for (int i = 1; i <= n; i++)
    27. {
    28. b[i] += b[i - 1];
    29. }
    30. for (int i = 1; i <= n; i++)
    31. {
    32. cout << b[i] << " ";
    33. }
    34. cout << endl;
    35. return 0;
    36. }

    二维差分

    现在需令阴影部分全部+c,则

    b(x1,y1)+=c;(蓝色框所选a+=c)

    b(x2+1,y1)-=c(紫色框a-=c)

    b(x1,y2+1)-=c(红色框a-=c)

    b(x2+1,y2+1)+=c(红紫公共区域a+=c)

    b的构造思路与一维差分类似

    输入一个 n 行 m 列的整数矩阵,再输入 q 个操作,每个操作包含五个整数 x1,y1,x2,y2,c,其中 (x1,y1) 和 (x2,y2)表示一个子矩阵的左上角坐标和右下角坐标。

    每个操作都要将选中的子矩阵中的每个元素的值加上 c。

    请你将进行完所有操作后的矩阵输出。

    1. #include
    2. #include
    3. using namespace std;
    4. const int N = 1010;
    5. int a[N][N];
    6. int b[N][N];
    7. void insert(int x1, int y1, int x2, int y2,int c)
    8. {
    9. b[x1][y1] += c;
    10. b[x2 + 1][y1] -= c;
    11. b[x1][y2 + 1] -= c;
    12. b[x2 + 1][y2 + 1] += c;
    13. }
    14. int main()
    15. {
    16. int n, m, q;
    17. cin >> n >> m >> q;
    18. for (int i = 1; i <= n; i++)
    19. {
    20. for (int j = 1; j <= m; j++)
    21. {
    22. cin >> a[i][j];
    23. insert(i, j, i, j, a[i][j]);
    24. }
    25. }
    26. while (q--)
    27. {
    28. int x1, y1, x2, y2, c;
    29. cin >> x1 >> y1 >> x2 >> y2 >> c;
    30. insert(x1, y1, x2, y2, c);
    31. }
    32. for (int i = 1; i <= n; i++)//求二维前缀和并输出
    33. {
    34. for (int j = 1; j <= m; j++)
    35. {
    36. b[i][j] += b[i][j - 1] + b[i - 1][j] - b[i - 1][j - 1];
    37. cout << b[i][j] << " ";
    38. }
    39. cout << endl;
    40. }
    41. return 0;
    42. }

  • 相关阅读:
    Spark 3.0 - 5.ML Pipeline 实战之电影影评情感分析
    SDN实验(三)——集线器hub的实现
    读透业务安全白皮书——未来四大趋势
    Python数据分析与机器学习38-Xgboost算法
    [游戏开发][Unity]编辑器Assets操作API大全
    视频融合云平台EasyCVR进程启动时报错“update cluster server”的排查及解决方法
    工业交换机选用技巧
    玩全栈,做自己喜欢做的事,写自己喜欢写的代码
    Shadowing Japanese Unit3
    MySql 5.7.38下载安装教程 ,并实现在Navicat操作MySql
  • 原文地址:https://blog.csdn.net/m0_73612605/article/details/136337404