单调栈好题,非常独特的视角。 题解 # 栈中的每一个元素{x,i}代表的是一组连续的多米诺,使得如果我们如果推倒 x 处的多米诺,从第 i 个开始一直到下一组的多米诺都会被推掉。所以我们处理新的多米诺的时候,要先把当前多米诺够得到的多米诺组弹出,最后栈顶的元素就是最近的够不着的多米诺,也就是当前多米诺的答案。 Code # #include <bits/stdc++.h> #define forn(i, n) for (int i = 0; i < int(n); ++i) #define F first #define S second #define all(x) (x).begin(),(x).end() using namespace std; using pii= pair<int, int>; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin>>n; vector<int> x(n),h(n),id(n); iota(all(id),0); forn(i,n){ cin>>x[i]>>h[i]; } sort(all(id),[&](int a,int b){return x[a]<x[b];}); vector<int> ans(n); stack<pii> stk; stk.push({1e9,n}); for(int i=n-1;i>=0;i--){ int ii=id[i]; while(!stk.empty()&&x[ii]+h[ii]>stk.top().F) stk.pop(); ans[ii]=(stk.empty()?1:stk.top().S-i); stk.push({x[ii],i}); } for(auto it:ans) cout<<it<<' '; return 0; }