abc283 F - Permutation Distance

题意:

给定 1n 的排列 P,对每个 i[1,n],计算 minji{|PiPj|+|ij|}

n2e5

思路:

我超,俩绝对值怎么办?硬拆就完事了!

i>j,Pi>Pji+Pi+min{jPj}i>j,Pi<PjiPi+min{j+Pj}i<j,Pi>Pji+Pi+min{jPj}i<j,Pi<PjiPi+min{j+Pj}

经典二维偏序,树状数组或者线段树维护最值,做四次

const signed N = 2e5 + 5, INF = 1e9;
int n, a[N], ans[N];

int tr[N * 4];
void init() {
    fill(tr, tr + N * 4, INF);
}
void modify(int u, int l, int r, int p, int x) { //单点修改
    if(l == r) return tr[u] = x, void();
    int mid = (l + r) / 2;
    if(p <= mid) modify(u * 2, l, mid, p, x);
    else modify(u * 2 + 1, mid + 1, r, p, x);
    tr[u] = min(tr[u * 2], tr[u * 2 + 1]);
}
int ask(int u, int l, int r, int x, int y) {
    if(x > y) return INF;
    if(x <= l && r <= y) return tr[u];
    int mid = (l + r) / 2, s = INF;
    if(x <= mid) s = min(s, ask(u * 2, l, mid, x, y));
    if(y > mid) s = min(s, ask(u * 2 + 1, mid + 1, r, x, y));
    return s;
}

void sol() {
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    
    fill(ans, ans + N, INF);
    
    init(); for(int i = 1; i <= n; i++) {
        ans[i] = min(ans[i], i + a[i] + ask(1, 1, n, 1, a[i] - 1));
        modify(1, 1, n, a[i], -i - a[i]);
    }
    init(); for(int i = 1; i <= n; i++) {
        ans[i] = min(ans[i], i - a[i] + ask(1, 1, n, a[i] + 1, n));
        modify(1, 1, n, a[i], -i + a[i]);
    }
    init(); for(int i = n; i >= 1; i--) {
        ans[i] = min(ans[i], -i + a[i] + ask(1, 1, n, 1, a[i] - 1));
        modify(1, 1, n, a[i], i - a[i]);
    }
    init(); for(int i = n; i >= 1; i--) {
        ans[i] = min(ans[i], -i - a[i] + ask(1, 1, n, a[i] + 1, n));
        modify(1, 1, n, a[i], i + a[i]);
    }
    
    for(int i = 1; i <= n; i++)
        cout << ans[i] << ' ';
}
posted @   Bellala  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
历史上的今天:
2022-01-03 cf1010 D. Mars rover(树)
点击右上角即可分享
微信分享提示