思路:
二分答案, 找到第一个不满足条件的位置
首先对于一个值来说, 所有这个值的区间肯定有交区间, 然后在这个交区间内不能出现比它小的数
所以我们check时从大的值开始考虑, 求出交区间后并标记(用并查集), 如果之后的区间被标记过,那就说明有矛盾
代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pli pair<LL, int> #define pii pair<int, int> #define piii pair<pii, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 5e5 + 10; struct node { int l, r, p; bool operator < (const node & rhs) & { return p > rhs.p; } }a[N], tmp[N]; int fa[N]; int Find(int x) { if(x == fa[x]) return x; else return fa[x] = Find(fa[x]); } int n; bool check(int m) { for (int i = 1; i <= m; i++) tmp[i] = a[i]; for (int i = 1; i <= n; i++) fa[i] = i; sort(tmp+1, tmp+1+m); for (int i = 1; i <= m; i++) { int j = i, l = tmp[i].l, r = tmp[i].r; while(j+1 <= m && tmp[j+1].p == tmp[i].p) { j++; l = max(l, tmp[j].l); r = min(r, tmp[j].r); } if(l > Find(r)) return false; while(r >= l) { if(fa[r] == r) fa[r] = Find(l-1), r--; else r = Find(r); } i = j; } return true; } int main() { int k; scanf("%d %d", &n, &k); for (int i = 1; i <= k; i++) { scanf("%d %d %d", &a[i].l, &a[i].r, &a[i].p); } int l = 1, r = k, m = l+r+1 >> 1; while(l < r) { if(check(m)) l = m; else r = m-1; m = l+r+1 >> 1; } printf("%d ", m+1); return 0; }