HELLO WORLD--一起加油(🍺)!|

kingwzun

园龄:3年6个月粉丝:111关注:0

2022-08-08 09:10阅读: 191评论: 0推荐: 0

前缀和 and 差分

前缀和

一维前缀和:
预处理: O(n)

S[i]=a[1]+a[2]+...a[i]

求区间[L,R]的和:O(1)

a[L]+...+a[R]=S[r]S[l1]

二维前缀和:.
预处理: O(nm)

S[i, j] = 第i行j列格子左上部分所有元素的和

求以(x1, y1)为左上角,(x2, y2)为右下角的子矩阵的和: O(1)

S[x2,y2]S[x11,y2]S[x2,y11]+S[x11,y11]

image

模板题

P2280 [HNOI2003]激光炸弹
洛谷
acwing

题意:
地图上有 N 个目标,,每个目标都有一个价值 Wi。每个炸弹有个范围,求一颗炸弹最多能炸掉地图上总价值为多少的目标。
思路:
二分前缀和
代码:

const int N = 5010;
int s[N][N];
int n,r;
void solve()
{
cin>>n>>r;
r = min(r, 5001);
for(int i=0;i<n;i++){
int x,y,w;
cin>>x>>y>>w;
s[x+1][y+1]+=w;
}
//预处理前缀和
for(int i=1;i<=5001;i++)
for(int j=1;j<=5001;j++)
s[i][j]+=s[i-1][j]+s[i][j-1]-s[i-1][j-1];
int ans=0;
for(int i=r;i<=5001;i++)
for(int j=r;j<=5001;j++)
ans=max(ans,s[i][j]-s[i-r][j]-s[i][j-r]+s[i-r][j-r]);
cout<<ans<<endl;
}

差分

思路:

  • 想要让[l,r]上面整体加上c,在一个长的数组上是无法实现单方面让[l,r]上加
  • 只有先让 l 右边的所有数先加上c, 在让 r+1右边的减去 c, 这样就可以让[l,r]上加上c

代码:

int insert(int l, int r, int c)
{
b[l] += c;
b[r + 1] -= c;
}

应用

增减序列
洛谷
acwing
原文
题意:
给定一个长度为 n 的数列 a1,a2,,an,每次可以选择一个区间 [l,r],使下标在这个区间内的数都加一或者都减一。

  1. 至少需要多少次操作才能使数列中的所有数都一样
  2. 并求出在保证最少次数的前提下,最终得到的数列可能有多少种

分析:
先求出差分数组
B[1]=A[1]
B[i]=A[i]A[i1] (2<=i<=n)

很明显题意1在差分数组的体现就是:B2...Bn 都为零,B1取值无所谓。

贪心:

  1. 我们可以,每一次选取BiBj2<=i,j<=n,而且这两个数,一个为正数,一个为负数

为什么要是正负配对?因为我们是要这个B序列2~n都要为0,所以这样负数增加,正数减少,就可以最快地到达目标为0的状态。

  1. 至于那些无法配对的数Bk可以选B1或者Bn+1,这两个不影响的数,进行修改。

所以说最少操作数就是min(p,q)+abs(pq)=max(p,q)
p为b序列中正数之和,而q为b序列中负数之和

我们知道经过操作后,数组的值就是b[1]的值。因此数组的情况就是b[1]可能的取值。然后我们贪心过程中,就只有第二步会改变b[1]的值,所以
最终序列a可能会有abs(pq)+1种情况。

代码:

const int N = 100010;
typedef long long LL;
int n;
int a[N], b[N];
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
for (int i = 1; i <= n; i ++ ) b[i] = a[i] - a[i - 1];
LL p = 0, q = 0;
for (int i = 2; i <= n; i ++ )
if (b[i] > 0) p += b[i];
else q -= b[i];
cout << max(p, q) << endl;
cout << abs(p - q) + 1 << endl;
return 0;
}

本文作者:kingwzun

本文链接:https://www.cnblogs.com/kingwz/p/15259183.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   kingwzun  阅读(191)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起