最近补题,写到了这个很有意思的差分,乍一看就是一个差分,仔细一看,要找的是货物种类最多的仓库编号,注意是种类!
所以,对每一次放货物,我们不能直接对差分数组操作,我们需要先把每一次操作存储起来,然后排序,进行相同种类的货物区间合并,对于排序规则,我们以种类为第一要素比较,然后比较左端点,左端点小的放在前面(便于后面进行区间合并),然后进行查分操作。
我们从第二个元素开始遍历,如果当前种类与前一个种类相同,并且存在交叉区间(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 ; }