码迷,mamicode.com
首页 > 其他好文 > 详细

前缀和

时间:2018-07-26 14:58:31      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:span   快速   inf   color   void   pre   [1]   数组   val   

一维前缀和

  • 作用:快速查询数组a[l]~a[r]的和,时间复杂度为o(1)。
  • 求法:例如数组a[],用一个数组sum[]来记录它的前n项和,例如sum[n]表示a[1]+a[2]+...+a[n]。
  •  1 int sum[1000];
     2 void init()
     3 {
     4     for(int i=1; i<=n; i++)
     5         sum[i]=sum[i-1]+a[i];
     6 }
     7 int query(int l, int r)
     8 {
     9     return sum[r]-sum[l-1]; 
    10 }

二维前缀和

  • 作用:快速查询数组a[][]任意二维区间的和
  • 求法:用一个数组sum[n][m]表示所有a[n‘][m‘]的和(1<=n‘<=n,1<=m‘<=m)。
  • 下面代码的例图。
  • 技术分享图片
  •  1 int sum[1000][1000];
     2 void init()
     3 {
     4     for(int i=1; i<=n; i++)
     5         for(int j=1; j<=m; j++)
     6             sum[i][j]=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]+a[i][j];
     7 }
     8 int query(int x1, int y1, int x2, int y2)
     9 {
    10     return sum[x2][y2]-sum[x2][y1-1]-sum[x1-1][y2]+sum[x1-1][y1-1];
    11 }

     

 一维差分

  • 作用:设数组为a[],对多次a数组上的区间[l,r]实现加减val的操作(将对区间的的操作转化为对两个端点的操作)。
  • 做法:
     1 int a[n];
     2 int d[n];
     3 int c[n];
     4 void init(int l, int r, int val)
     5 {
     6     d[l]+=val;d[r+1]-=val;
     7 }
     8 for(int    i=1; i<=n; i++)
     9 {
    10     c[i]=c[i-1]+d[i];
    11 }
    12 for(int i=1; i<=n; i++)
    13 {
    14     a[i]+=c[i];
    15 }

二维差分

  •  1 void init(int x1, int y1, int x2, int y2, int val)
     2 {
     3     sum[x1][y1] += val;
     4     sum[x1][y2 + 1] -= val;
     5     sum[x2 + 1][y1] -= val;
     6     sum[x2 + 1][y2 + 1] += val;
     7 }
     8 
     9 void get()
    10 {
    11     for(int i = 1; i <= n; i++)
    12         for(int j = 1; j <= n; j++)
    13             sum[i][j] += sum[i][j-1] + sum[i-1][j] - sum[i-1][j-1];
    14 }

     

 

前缀和

标签:span   快速   inf   color   void   pre   [1]   数组   val   

原文地址:https://www.cnblogs.com/dongdong25800/p/9371254.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!