差分数组。对于区间的货物种类,首先将所有相同编号的货物种类的区间,按照从小到大的顺序进行排列,其次按照差分数组的性质:
当我们希望对原数组的某一个区间[l,r]施加一个增量inc时,差分数组d对应的变化是:d[l]增加inc,d[r+1]减少inc,并且这种操作是可以叠加的。
当我们需要对原数组的不同区间施加不同的增量,我们只要按规则修改差分数组即可。
这道题目中,每次增量的数目为1。之后对于每个位置的不同货物的种数,进行一个前缀和,即可得到每个位置的不同货物的数目。
#include <bits/stdc++.h>
using namespace std;
#define M 100010
//维护一个差分数组存储各仓库货物种类数
int delta[M];
struct tag {
int l, r, d;
}a[M];
//若货物编号相等,则按左端点升序排列,否则按编号升序排列
bool comp(tag x, tag y) {
if(x.d == y.d)
return x.l < y.l;
return x.d < y.d;
}
int main() {
int n, m, ans;
cin >> n >> m;
for(int i = 1; i <= m; i++)
cin >> a[i].l >> a[i].r >> a[i].d;
sort(a + 1, a + m + 1, comp);
int temp_o = a[1].l, temp_d = a[1].r;
for(int j = 2; j <= m; j++) {
//出现新类型,差分数组端点变化
//同时刷新起点和终点
if(a[j].d != a[j-1].d) {
delta[temp_o]++;
delta[temp_d + 1]--;
temp_o = a[j].l;
temp_d = a[j].r;
} else {
if(a[j].l <= temp_d)
temp_d = max(temp_d, a[j].r);
//旧货物,进行区间合并或处理差分数组
else {
delta[temp_o]++;
delta[temp_d + 1]--;
temp_o = a[j].l;
temp_d = a[j].r;
}
}
}
//最后一次没处理
delta[temp_o]++;
delta[temp_d + 1]--;
//复原差分数组
for(int k = 1; k <= n; k++)
delta[k] += delta[k - 1];
ans = 0;
int a_max = 0;
for(int s = 1; s <= n; s++) {
//也可以逆序遍历,把等号改成大于或等于
if(delta[s] > a_max) {
ans = s;
a_max = delta[ans];
}
}
cout << ans;
return 0;
}
(新学了差分数组这一数据结构,初次接触,之后好好复习)