zoukankan      html  css  js  c++  java
  • CodeForces

    题目链接

    题目大意

      有n个会议,每个会议分为a,b两个会场,ab会场的开会时间各有一个时间端,问对于任意两个会议,有没有在同一个会场冲突,而在另一个会场没有冲突的情况。

    解题思路

      大体思路就是对于每一个会议,先在一个会场中找到与其冲突的所有会议,再在对应的另一个会场中找有没有与之不冲突的。
      具体做法是先以a会场的开始时间排序,然后再以排序后b会场的开始时间的最大值与结束时间的最小值建线段树,遍历每一个会议,二分出与当前会议冲突的会议区间,用线段树在b会场中找这个区间内的开始时间的最大值与结束时间的最小值,如果开始时间的最大值比当前会议的结束时间晚或者结束时间的最小值比当前会议的开始时间早,肯定是存在不冲突的会议的。然后在a和b颠倒再来一遍。

    代码

    const int maxn = 2e5+10;
    const int maxm = 2e3+10;
    struct I {
    	int x1, y1, x2, y2;
    	bool operator < (I a) const {
    		return x1==a.x1 ? y1<a.y1 : x1<a.x1;
    	}
    } a[maxn];
    int n;
    struct T {
    	int s, e;
    } tree[maxn<<2];
    void build(int rt, int l, int r) {
    	if (l==r) {
    		tree[rt].s = a[l].x2;
    		tree[rt].e = a[l].y2;
    		return;
    	}
    	int mid = (l+r)>>1;
    	build(rt<<1, l, mid);
    	build(rt<<1|1, mid+1, r);
    	tree[rt].s = max(tree[rt<<1].s, tree[rt<<1|1].s);
    	tree[rt].e = min(tree[rt<<1].e, tree[rt<<1|1].e);
    }
    int ask1(int rt, int l, int r, int a, int b) {
    	if (l>=a && r<=b) return tree[rt].s;
    	int mid = (l+r)>>1;
    	int maxx = 0;
    	if (a<=mid) maxx = max(maxx, ask1(rt<<1, l, mid, a, b));
    	if (b>mid) maxx = max(maxx, ask1(rt<<1|1, mid+1, r, a, b));
    	return maxx;
    }
    int ask2(int rt, int l, int r, int a, int b) {
    	if (l>=a && r<=b) return tree[rt].e;
    	int mid = (l+r)>>1;
    	int minn = INF;
    	if (a<=mid) minn = min(minn, ask2(rt<<1, l, mid, a, b));
    	if (b>mid) minn = min(minn, ask2(rt<<1|1, mid+1, r, a, b));
    	return minn; 
    }
    int solve(int x) {
    	int l = 1, r = n+1;
    	while(l<r) {
    		int mid = (l+r)>>1;
    		if (a[mid].x1>a[x].y1) r = mid;
    		else l = mid+1;
    	}
    	return l-1;
    }
    int main() {
    	cin >> n;
    	for (int i = 1; i<=n; ++i) {
    		cin >> a[i].x1 >> a[i].y1;
    		cin >> a[i].x2 >> a[i].y2;
    	}
    	sort(a+1, a+n+1); build(1, 1, n);
    	a[n+1] = {INF, INF, INF, INF};
    	int ok = 1;
    	for (int i = 1; i<=n; ++i) {
    		int x = solve(i);
    		if (x==i) continue;
    		int l = ask1(1, 1, n, i, x);
    		int r = ask2(1, 1, n, i, x);
    		if (r<a[i].x2 || l>a[i].y2) ok = 0;
    	}
    	for (int i = 1; i<=n; ++i) swap(a[i].x1, a[i].x2), swap(a[i].y1, a[i].y2);
    	sort(a+1, a+n+1); build(1, 1, n);
    	for (int i = 1; i<=n; ++i) {
    		int x = solve(i);
    		if (x==i) continue;
    		int l = ask1(1, 1, n, i, x);
    		int r = ask2(1, 1, n, i, x);
    		if (r<a[i].x2 || l>a[i].y2) ok = 0;
    	}
    	if (ok) cout << "YES" << endl;
    	else cout << "NO" << endl;
    	return 0;	
    }
    
  • 相关阅读:
    3.5缺少动态连接库.so--cannot open shared object file: No such file or directory
    PHP中的变量详解
    Python类的实例属性详解
    Docker中的镜像分层技术详解
    如何编写优雅的代码?
    Node.js在不同平台的安装方法步骤详解
    Python3.X新特性之print和exec
    Django中如何配置Database缓存?
    Ajax中eval的使用详解
    如何创建和使用XMLHttpRequest对象?
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/14409983.html
Copyright © 2011-2022 走看看