哇可把我牛逼坏了具体内容过段时间在写

#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