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);
}