前缀和
降低区间和查询问题的时间复杂度,分一维和二维
一种数据预处理手段,一般配合其他算法查分、二分搜索
二分:容斥原理。
sum[i][j] = sum[i - 1][j] +sum[i][j - 1] - sum[i - 1][j - 1] + a[i][j];
差分
前缀和相对的策略,可当做求和的逆运算
a[l]++; a[r + 1]--;
洛谷 P1672
https://www.luogu.com.cn/problem/P1672
牛的个数: C
收到运来的饲料: F1
到 D 天为止
剩下饲料:F2
判断饲料最近一次运到的时候
原理:F1 + ( D 天到 x 天的和 ) = F2
输入数据,差分记录
cin >> c >> f1 >> f2 >> d;
for (int i = 1; i <= n; ++ i ) {
int l, r;
cin >> l >> r;
ll = min(ll, l);
rr = max(rr, r);
diff[l]++;
diff[r + 1]--;
}
差分转前缀
for (int i = ll; i <= rr; ++ i) {
sum[i] = sum[i - 1] + diff[i];
}
时间从后往前推,算出最近的,加sum[i]的数,使数达到F1
int x = d + 1; //天数
while (f1 != f2) {
// f2 += sum[--x]; 优化
f2 += sum[x];
x--;
}
输出
cout << x;
完整代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int c, f1, f2, d, a[N], sum[N], rr = -INT_MAX, ll = INT_MAX;
signed main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> c >> f1 >> f2 >> d;
for (int i = 1; i <= c; ++i) {
int l, r;
cin >> l >> r;
a[l]++;
a[r + 1]--;
ll = min(ll, l);
rr = max(rr, r);
}
for (int i = ll; i <= rr; ++i) {
sum[i] = sum[i - 1] + a[i];
}
int x = d + 1;
while (f2 != f1) {
f2 += sum[--x];
}
cout << x;
}
标签:f2,洛谷,rr,int,sum,P1672,--,ll
From: https://www.cnblogs.com/Mono-Awen/p/18438503