ACL Contest 1

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

原文地址:https://www.cnblogs.com/tomori/p/13704577.html