AcWing 136 鄰值查詢(連結串列)
阿新 • • 發佈:2020-07-18
解題思路
如果將所有數字按從大到小排序,並且從編號最大的數開始找的話,那麼他的左右兩邊的數肯定就是離他最近的數,計算之後把編號最大的數刪掉,那麼編號次大的數相當於之前編號最大的數...所以利用連結串列來做到O(1)刪除,就能在O(nlogn)的時間內解題。
程式碼
const int maxn = 1e5+10; P a[maxn], ans[maxn]; int p[maxn]; struct NODE { int l,r; } chain[maxn]; int main() { int n; scanf("%d",&n); for (int i = 1; i<=n; ++i) { scanf("%lld",&a[i].first); a[i].second = i; } sort(a+1,a+n+1); a[0] = {-3e9,0}, a[n+1] = {3e9,n+1}; for (int i = 1; i<=n; ++i) { chain[i] = {i-1,i+1}; p[a[i].second] = i; } for (int i = n; i>1; --i) { int pos = p[i], left = chain[pos].l, right = chain[pos].r; ll v_l = a[pos].first-a[left].first, v_r = a[right].first-a[pos].first ; if (v_l<=v_r) ans[i] = {v_l,a[left].second}; else ans[i] = {v_r,a[right].second}; chain[left].r = right, chain[right].l = left; } for (int i = 2; i<=n; ++i) printf("%d %d\n",ans[i].first, ans[i].second); return 0; }