1.AcWing797. 差分
分析思路:
代码实现:
//差分:前缀和的逆运算
#include<iostream>
using namespace std;
const int N = 100010;
int a[N],b[N];
int n,m;
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
b[i]=a[i]-a[i-1];//a[i]为b[i]的前缀和数组
}
while(m--)
{
int l,r,c;
cin>>l>>r>>c;
b[l]+=c;
b[r+1]-=c;
}
for (int i = 1; i <= n; i++)
{
a[i] = b[i] + a[i - 1]; //前缀和运算
printf("%d ", a[i]);
}
return 0;
}
2.AcWing 503. 借教室
分析思路:
差分:因为本题要对区域时间进行天数的减法,所有使用差分。
二分:由于随着订单数量的增加,每天可用教室的数量一定单调下降。
因此我们可以二分出最后一天没出现负值的订单编号。
代码实现:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1000010;
int r[N],d[N],s[N],t[N];
LL b[N];//差分数组
int n,m;
bool check(int mid)
{
//构建差分数组
for(int i=1;i<=n;i++)b[i]=r[i]-r[i-1];
for(int i=1;i<=mid;i++)
{
b[s[i]]-=d[i];
b[t[i]+1]+=d[i];
}
for(int i=1;i<=n;i++)
{
b[i]+=b[i-1];//前缀和公式
if(b[i]<0) return true;
}
return false;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++) scanf("%d",&r[i]);
for(int i=1;i<=m;i++) scanf("%d%d%d",&d[i],&s[i],&t[i]);
if(!check(m))
{
puts("0");
return 0;
}
int l=1,r=m;
while(l<r)
{
int mid = l+r>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
printf("-1\n%d\n",r);
}