目录
一维差分
参考资料:
【C++】一维、二维差分+模板+例题_c语言差分练习题-CSDN博客
模板题目:
https://www.luogu.com.cn/problem/P2367
模板代码:
#include <stdint.h>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <thread>
#include <iostream>
using namespace std;
const int maxn = 5e6+5;
int a[maxn];
int diff[maxn];
void insert(int l, int r, int c)
{
diff[l] += c;
diff[r+1] -= c;
}
int main() {
int n,p;
cin >> n >> p;
for(int i=1;i<=n;++i)
{
cin >> a[i];
}
a[0]=0;
for(int i=1;i<=n;++i)
{
diff[i] = a[i] - a[i-1];
}
int l,r,c;
while(p--)
{
cin >> l >> r >> c;
insert(l, r, c);
}
int ans = maxn, sum =0;
for(int i=1;i<=n;++i)
{
sum+=diff[i];
ans = min(ans, sum);
}
cout << ans <<endl;
// system("pause");
return 0;
}
二维差分
参考资料:
算法基础(五)| 差分算法及模板详解-腾讯云开发者社区-腾讯云
模板题目:
https://www.luogu.com.cn/problem/P5542
模板代码:
#include <stdint.h>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <thread>
#include <iostream>
using namespace std;
const int maxn = 1005;
int a[maxn][maxn]; // 以下坐标起始点都为(1,1)
int diff[maxn][maxn]; // 表示从(1,1)到(i,j)的差分矩阵
int ans[maxn][maxn]; // 最终结果矩阵
void init()
{
memset(a, 0, sizeof(a));
memset(diff, 0, sizeof(diff));
memset(ans, 0, sizeof(ans));
}
void build_diff_array(int n, int m)
{
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
diff[i][j] = a[i][j] - a[i - 1][j] - a[i][j - 1] + a[i - 1][j - 1];
}
}
return;
}
void region_add(int x1, int y1, int x2, int y2, int val) // 左上角和右下角
{
diff[x1][y1] += val;
diff[x1][y2 + 1] -= val;
diff[x2 + 1][y1] -= val;
diff[x2 + 1][y2 + 1] += val;
}
void build_ans_array(int n, int m)
{
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
ans[i][j] = diff[i][j] + ans[i - 1][j] + ans[i][j - 1] - ans[i - 1][j - 1];
}
}
return;
}
int main()
{
int n, k, x1, y1, x2, y2;
scanf("%d%d", &n, &k);
init();
while (n--)
{
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
region_add(x1+1, y1+1, x2, y2, 1); // 这里注意坐标位置
}
build_ans_array(1000, 1000);
int sum = 0;
for (int i = 1; i <= 1000; ++i)
{
for (int j = 1; j <= 1000; ++j)
{
if (ans[i][j] == k)
sum++;
}
}
printf("%d\n", sum);
return 0;
}
补充练习题
https://codeforces.com/contest/2000/problem/E
ac代码:
#include <stdint.h>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <thread>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5;
/*int a[maxn][maxn]; // 以下坐标起始点都为(1,1)
int diff[maxn][maxn]; // 表示从(1,1)到(i,j)的差分矩阵
int ans[maxn][maxn]; // 最终结果矩阵
int h[maxn];*/
/*void init()
{
memset(a, 0, sizeof(a));
memset(diff, 0, sizeof(diff));
memset(ans, 0, sizeof(ans));
}
void build_diff_array(int n, int m)
{
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
diff[i][j] = a[i][j] - a[i - 1][j] - a[i][j - 1] + a[i - 1][j - 1];
}
}
return;
}*/
void region_add(int x1, int y1, int x2, int y2, int val, vector<vector<int>> &diff) // 左上角和右下角
{
diff[x1][y1] += val;
diff[x1][y2 + 1] -= val;
diff[x2 + 1][y1] -= val;
diff[x2 + 1][y2 + 1] += val;
}
void build_ans_array(int n, int m, vector<vector<int>> &diff, vector<vector<int>> &ans)
{
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
ans[i][j] = diff[i][j] + ans[i - 1][j] + ans[i][j - 1] - ans[i - 1][j - 1];
}
}
return;
}
void slove()
{
int n, m, k, w;
scanf("%d%d%d", &n, &m, &k);
vector<vector<int>> diff(n + 5, vector<int>(m + 5, 0));
vector<vector<int>> ans(n + 5, vector<int>(m + 5, 0));
scanf("%d", &w);
vector<int> h(w + 5, 0);
for (int i = 0; i < w; ++i)
{
scanf("%d", &h[i]);
}
sort(h.begin(), h.begin() + w, greater<int>());
for (int i = 1; i <= n - k + 1; ++i)
{
for (int j = 1; j <= m - k + 1; ++j)
{
region_add(i, j, i + k - 1, j + k - 1, 1, diff);
}
}
build_ans_array(n, m, diff, ans);
vector<int> vec;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
vec.push_back(ans[i][j]);
// printf("%d ", ans[i][j]);
// if(j==m)
// printf("\n");
}
}
sort(vec.begin(), vec.end(), greater<int>());
ll sum = 0;
for (int i = 0; i < w; ++i)
{
// printf("i=%d %d %d\n",i, vec[i],h[i]);
sum += (ll)vec[i] * h[i];
}
printf("%lld\n", sum);
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
slove();
}
return 0;
}