不知是否思路问题 求大佬看看
查看原帖
不知是否思路问题 求大佬看看
813591
ZYZ1021楼主2023/10/15 19:38
/*
	记录包含x的区间不重复地取两头(l<=x&&r>=x);
	其余分两类:
		1.在x左的区间(r<x) 2.在x右的区间(l>x)
	解决1:
		先按照右端点排序, 
		若与左侧所有区间有交集(r>=Lmin),取左端;
	解决2:
		先按照左端点排序, 
		若与右侧所有区间有交集(l<=Rmax),取右端; 
*/
#include <bits/stdc++.h>
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC optimize(2)
using namespace std;
const int N = 2e5 + 4;

struct pt{int L, R;}Left[N], Right[N];
int n, m, x, Lmin, Rmax, pl, pr;
bool vis[N];
priority_queue<int, vector<int>, greater<int> > ans;

bool cmp1(pt A, pt B){return A.R <= B.R;}
bool cmp2(pt A, pt B){return A.L <= B.L;}
void Push(int X){if(!vis[X]) ans.push(X), vis[X] = 1;};

int main(){
	int i, j, l, r; scanf("%d %d %d", &n, &m, &x);
	vis[x] = 1;
	
	for(i = 1;i <= m;i ++){
		scanf("%d %d", &l, &r); 
		/*中间*/if(l <= x && r >= x){Push(l), Push(r); Lmin = min(Lmin, l); Rmax = max(Rmax, r);} 
		/*左侧*/else if(r < x) Left[++ pl].L = l, Left[pl].R = r;
		/*右侧*/else Right[++ pr].L = l, Right[pr].R = r;
	}
	
	sort(Left + 1, Left + pl + 1, cmp1);
	for(i = 1;i <= pl;i ++) if(Left[i].R >= Lmin) Push(Left[i].L), Lmin = Left[i].L;
	sort(Right + 1, Right + pr + 1, cmp2);
	for(i = 1;i <= pr;i ++) if(Right[i].L <= Rmax) Push(Right[i].R), Rmax = Right[i].R;
	
	while(!ans.empty()) printf("%d ", ans.top()), ans.pop();
	return 0;
}
2023/10/15 19:38
加载中...