A - Reachable Towns
参考了题解:单调栈+并查集
这题一开始用的是O(n^2)枚举+并查集,T掉了
做法:
对原序列的第一维坐标升序排序,维护一个以第二维坐标为参照的单调不增的单调栈,栈中存放(pos, y)二元组,这个表示城市pos所在的集合中最小的y坐标。
#include<iostream>
#include<algorithm>
using namespace std;
#define PII pair<int, int>
const int N = 200010, INF = 0x3f3f3f3f;
typedef struct{
int x, y, pos;
}state;
state a[N];
int cnt[N], p[N];
int n;
PII stk[N];
int tt = -1;
int cmp(const state &a, const state &b){
return a.x < b.x;
}
int find(int x){
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
int main(){
cin >> n;
for(int i = 0; i < n; i ++){
int x, y;
cin >> x >> y;
a[i] = {x, y, i};
}
for(int i = 0; i < n; i ++) p[i] = i, cnt[i] = 1;
sort(a, a + n, cmp);
for(int i = 0; i < n; i ++){
if(tt == -1) stk[++ tt] = {a[i].pos, a[i].y};
else{
int minv = a[i].y;
while(~tt && a[i].y > stk[tt].second){
minv = min(minv, stk[tt].second);
int x = find(a[i].pos), y = find(stk[tt].first);
if(x != y){
p[x] = y;
cnt[y] += cnt[x];
}
tt --;
}
stk[++ tt] = {a[i].pos, minv};
}
}
for(int i = 0; i < n; i ++) cout << cnt[find(i)] << endl;
return 0;
}
剩下的题。。。慢慢补吧。
123