Hướng dẫn giải của Bedao Mini Contest 26 - Bán sách
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Tạo ~1~ cạnh có hướng từ ~i~ đến ~j~ nếu người ~i~ gây ảnh hưởng lên người ~j~ được. Từ đó số lượng sách ít nhất cần phải cho là số lượng đỉnh ~u~ có ~deg_{in}u=0~. Độ phức tạp ~O(N^2)~. Để cái tiến ta sẽ dùng stack. Ta sort những người trong thành phố theo tọa độ của ~x_i~ tăng dần. Sau đó duyệt tăng dần theo tọa độ ~x_i~ và dùng stack để lưu lại những người chưa bị ảnh hưởng bởi người nào hết. Duyệt lại ~1~ lần nữa cho chiều giảm dần của ~x_i~. Độ phức tạp ~O(N)~.
#include<bits/stdc++.h> #define pb push_back #define pli pair<ll,ll> #define fi first #define se second #define fastio ios_base::sync_with_stdio(false); cin.tie(NULL); using namespace std; using ll=long long; const ll maxn=5e5+10; const ll inf=1e18; const ll mod=1e9+7; ll n; struct qq { ll x,e; bool operator<(const qq&o) { if(x==o.x) return e<o.e; return x<o.x; } }a[maxn]; deque<pli>dq; vector<ll>g[maxn]; ll deg[maxn]; void solve() { cin >> n ; for(int i=1;i<=n;i++) { cin >> a[i].x >> a[i].e; } sort(a+1,a+n+1); for(int i=1;i<=n;i++) { // xi-xj>=ei-ej -> xi-ei>=xj-ej while(dq.size()>0&&dq.back().se>=a[i].x-a[i].e) { g[i].pb(dq.back().fi); deg[dq.back().fi]++; dq.pop_back(); } dq.pb({i,a[i].x-a[i].e}); } dq.clear(); for(int i=n;i>=1;i--) { if(i<=n&&a[i].x==a[i+1].x&&a[i].e==a[i+1].e) continue; while(dq.size()>0&&dq.back().se<=a[i].x+a[i].e) { g[i].pb(dq.back().fi); deg[dq.back().fi]++; dq.pop_back(); } dq.pb({i,a[i].x+a[i].e}); } ll ans=0; for(int i=1;i<=n;i++) { if(deg[i]==0) ans++; } cout << ans; } int main() { fastio //freopen(TASKNAME".INP","r",stdin); //freopen(TASKNAME".OUT","w",stdout); solve(); }
Bình luận
Độ phức tạp O(NlogN) chứ sort tốn O(NlogN) mà