思路
思路还是很显然的,简单总结一下思路:
- 首先,将圆环从点 \(1\) 到 \(2N\) 切开,并将其拉直成一条直线。
- 在切开状态下,原来的弦变成了直线上的曲线。我们需要判断这些曲线之间是否存在交点。
- 在切开状态下,曲线之间的交点等价于满足 \(A_i < A_j < B_i < B_j\) 的不同曲线 \(i\) 和 \(j\) 的存在。
- 为了判断曲线之间是否存在交点,我们可以使用栈来管理曲线。首先,准备一个空栈 \(S\)。
- 遍历直线上的每个点,按顺序执行以下操作:
- 如果当前点是某个曲线的左端点,将该曲线的标识符加入栈 \(S\) 的末尾。
- 如果当前点是某个曲线的右端点,从栈 \(S\) 的末尾移除一个元素。
- 如果移除的元素不是当前曲线的标识符,说明存在交点,返回结果并终止程序。
- 如果程序在遍历结束后没有返回结果,说明曲线之间不存在交点。
这种使用栈的算法能够在 \(O(N)\) 的时间复杂度内判断曲线之间是否存在交点。
代码
#include<bits/stdc++.h>
using namespace std;
pair<int,int> s[400010];
int stk[400010];
signed main() {
int n;
cin>>n;
for(int i=0;i<n;i++){
int a,b;
cin>>a>>b;
if(a>b) swap(a,b);
s[a-1]={0,i};
s[b-1]={1,i};
}
int p=0;
for(int i=0;i<2*n;i++) {
int t=s[i].first, num=s[i].second;
if(t==0) stk[++p]=num;
else {
if(stk[p]!=num) {
cout<<"Yes";
return 0;
}
p--;
}
}
cout<<"No";
return 0;
}
标签:存在,Chords,int,题解,切开,曲线,ABC338E,交点
From: https://www.cnblogs.com/merlinkkk/p/18306134