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