#include <iostream> #include <cstdio> #include <stdio.h> #include <cmath> #include <cstring> #include <algorithm> #include <string> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #define INF 0x3f3f3f3f #define ll long long #define lowbit(x) (x&(-x)) #define eps 0.00000001 #define pn printf("\n") #define ms(x,y) memset(x,y,sizeof(x)) using namespace std; const int maxn = 1e5+7; struct node{ int x, r; int ind; int pos, lt, rt; // 自己位置, 区间左端点, 区间右端点 int lc, rc; bool operator < (const node& c) const { return x < c.x; } }p[maxn]; int n; int MIN[maxn << 2], MAX[maxn << 2]; int ans[maxn]; void build(int i, int b, int e) { if(b == e) { MIN[i] = MAX[i] = p[e].pos; return ; } int mid = (b + e) >> 1; build(i << 1, b, mid); build(i << 1 | 1, mid+1, e); MIN[i] = min(MIN[i << 1], MIN[i << 1 | 1]); MAX[i] = max(MAX[i << 1], MAX[i << 1 | 1]); } void updateMIN(int i, int b, int e, int pos, int val) { if(b == e) { MIN[i] = val; return ; } int mid = (b + e) >> 1; if(pos <= mid) updateMIN(i << 1, b, mid, pos, val); else updateMIN(i << 1 | 1, mid+1, e, pos, val); MIN[i] = min(MIN[i << 1], MIN[i << 1 | 1]); } int queryMIN(int i, int b, int e, int l, int r) { if(b >= l && e <= r) return MIN[i]; int mid = (b + e) >> 1; if(r <= mid) return queryMIN(i << 1, b, mid, l, r); else if(l > mid) return queryMIN(i << 1 | 1, mid+1, e, l, r); else return min(queryMIN(i << 1, b, mid, l, r), queryMIN(i << 1 | 1, mid+1, e, l, r)); } void updateMAX(int i, int b, int e, int pos, int val) { if(b == e) { MAX[i] = val; return ; } int mid = (b + e) >> 1; if(pos <= mid) updateMAX(i << 1, b, mid, pos, val); else updateMAX(i << 1 | 1, mid+1, e, pos, val); MAX[i] = max(MAX[i << 1], MAX[i << 1 | 1]); } int queryMAX(int i, int b, int e, int l, int r) { if(b >= l && e <= r) return MAX[i]; int mid = (b + e) >> 1; if(r <= mid) return queryMAX(i << 1, b, mid, l, r); else if(l > mid) return queryMAX(i << 1 | 1, mid+1, e, l, r); else return max(queryMAX(i << 1, b, mid, l, r), queryMAX(i << 1 | 1, mid+1, e, l, r)); } int LT(int pos, int R) { int l = 1, r = pos, mid; while(l < r) { mid = (l + r) >> 1; if(p[pos].x - p[mid].x > R) l = mid + 1; else r = mid; } return l > pos ? pos : l; } int RT(int pos, int R) { int l = pos, r = n, mid; while(l < r) { mid = (l + r) >> 1; if(p[mid].x - p[pos].x <= R) l = mid + 1; else r = mid; } return p[l].x - p[pos].x <= R ? l : l-1; } void debug() { for(int i=1;i<=n;i++) cout << i << ": " << p[i].lt << ", " << p[i].rt << endl; } int cmpMIN(node a, node b) { return a.lt == b.lt ? (a.rt == b.rt ? a.r > b.r : a.rt > b.rt): a.lt < b.lt; } int cmpMAX(node a, node b) { return a.rt == b.rt ? (a.lt == b.lt ? a.r < b.r : a.lt > b.lt) : a.rt < b.rt; } int main() { scanf("%d", &n); for(int i=1;i<=n;i++) { scanf("%d%d", &p[i].x, &p[i].r); p[i].ind = i; } sort(p+1, p+1+n); for(int i=1;i<=n;i++) { p[i].pos = i; p[i].lt = LT(i, p[i].r); p[i].rt = RT(i, p[i].r); } // debug(); build(1,1,n); // 从右向左,检查右区间 sort(p+1, p+1+n, cmpMAX); for(int i=n;i>0;i--) { int tpMAX = queryMAX(1, 1, n, p[i].lt, p[i].rt); p[i].rc = tpMAX - p[i].pos; p[i].rt = max(p[i].rt, tpMAX); updateMAX(1, 1, n, p[i].pos, tpMAX); } // 从左向右,检查左区间 sort(p+1, p+1+n, cmpMIN); for(int i=1;i<=n;i++) { int tpMIN = queryMIN(1, 1, n, p[i].lt, p[i].rt); p[i].lc = p[i].pos - tpMIN; p[i].lt = min(p[i].lt, tpMIN); updateMIN(1, 1, n, p[i].pos, tpMIN); } // 从右向左,检查右区间 sort(p+1, p+1+n, cmpMAX); for(int i=n;i>0;i--) { int tpMAX = queryMAX(1, 1, n, p[i].lt, p[i].rt); p[i].rc = tpMAX - p[i].pos; p[i].rt = max(p[i].rt, tpMAX); updateMAX(1, 1, n, p[i].pos, tpMAX); } // 从左向右,检查左区间 sort(p+1, p+1+n, cmpMIN); for(int i=1;i<=n;i++) { int tpMIN = queryMIN(1, 1, n, p[i].lt, p[i].rt); p[i].lc = p[i].pos - tpMIN; p[i].lt = min(p[i].lt, tpMIN); updateMIN(1, 1, n, p[i].pos, tpMIN); } for(int i=1;i<=n;i++) ans[p[i].ind] = p[i].lc + p[i].rc + 1; for(int i=1;i<=n;i++) { if(i != 1) printf(" "); printf("%d", ans[i]); } pn; }
哇可把我牛逼坏了具体内容过段时间在写
猜你喜欢
转载自www.cnblogs.com/HazelNut/p/8948973.html
今日推荐
周排行