最近补题,写到了这个很有意思的差分,乍一看就是一个差分,仔细一看,要找的是货物种类最多的仓库编号,注意是种类!
所以,对每一次放货物,我们不能直接对差分数组操作,我们需要先把每一次操作存储起来,然后排序,进行相同种类的货物区间合并,对于排序规则,我们以种类为第一要素比较,然后比较左端点,左端点小的放在前面(便于后面进行区间合并),然后进行查分操作。
我们从第二个元素开始遍历,如果当前种类与前一个种类相同,并且存在交叉区间(a[i].l <= a[i-1].r)我们就合并区间,否则我们进行差分操作。
#include<bits/stdc++.h>
#define int long long
typedef unsigned long long ull;
typedef long long ll;
using namespace std;
const int N = 1e3 + 10;
const int mod = 1e9 + 7;
struct box{ //创建结构体
int l,r,num;
};
bool cmp(box &x,box &y){ //排序规则
if(x.num == y.num){
return x.l < y.l;
}
return x.num < y.num;
}
void solve(){
int n,m;
cin>>n>>m;
vector<box> a(m+1);
for (int i = 1; i <= m; ++i) { //存储每次操作
cin>>a[i].l>>a[i].r>>a[i].num;
}
sort(a.begin()+1,a.end(),cmp);//排序
int b[m+1];
memset(b,0,sizeof b);
//区间合并
int st = a[1].l,ed = a[1].r;
for (int i = 2; i <= m; ++i) {
if(a[i].num == a[i-1].num && a[i].l <= ed){ //种类相同且存在交叉区间
ed = max(ed,a[i].r);
} else{ //差分操作和更新st,ed
b[st]++;
b[ed+1]--;
st = a[i].l;
ed = a[i].r;
}
}
b[st]++; //最后会少进行一次差分操作
b[ed+1]--;
int maxx = -1,sum = 0,ans = 0;
for (int i = 1; i <= n; ++i) {
sum += b[i]; //差分求每一个仓库的物品种类数和结果
if(sum > maxx){
maxx = sum;
ans = i;
}
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(NULL),cout.tie(NULL);
int t = 1;
cin>>t;
while(t--){
solve();//1 2 3 4 5
}
return 0 ;
}

京公网安备 11010502036488号