class Solution {
public:
int getarea(vector<int>& a, vector<int>& b, vector<int>& c){
int x1 = b[0] - a[0], y1 = b[1] - a[1], x2 = c[0] - a[0], y2 = c[1] - a[1];
return x1 * y2 - x2 * y1;
}
vector<vector<int>> outerTrees(vector<vector<int>>& trees) {
int n = trees.size(), pos = 1;
vector<vector<int>> ans;
vector<int> dp(n + 5), vis(n + 1);
sort(trees.begin(), trees.end(), [](vector<int>& a, vector<int>& b){
return a[0] == b[0] ? a[1] <= b[1] : a[0] <= b[0];
});
for(int i = 1; i < n; i++){
while(pos >= 2){
if(getarea(trees[dp[pos - 2]], trees[dp[pos - 1]], trees[i]) < 0){
vis[dp[pos - 1]] = 0; pos--;
}else break;
}
dp[pos++] = i; vis[i] = 1;
}
int len = pos;
for(int i = n - 1; i >= 0; i--){
if(vis[i]) continue;
while(pos >= len + 1){
if(getarea(trees[dp[pos - 2]], trees[dp[pos - 1]], trees[i]) < 0){
vis[dp[pos - 1]] = 0; pos--;
}else break;
}
dp[pos++] = i;
}
for(int i = 0; i < pos - 1; i++){ // 起始点会被重复加入
ans.push_back(trees[dp[i]]);
}
return ans;
}
};