【封印宝石——线段树】

题目

【封印宝石——线段树】_第1张图片

分析

封印宝石题解https://www.acwing.com/solution/content/261922/

代码

#include 
using namespace std;
using pll = pair;
#define x first
#define y second

const int N = 1e5+10;

struct node
{
    int l, r;
    int v1, v2;
    int i1, i2;
} tr[4 * N];

int n, k, a[N], b[N];

bool cmp(pll a, pll b)
{
    if(a.x != b.x) return a.x > b.x;
    return a.y < b.y;
}
void pushup(node &u, node &l, node &r)
{
    static pll t[4];
    t[0] = {l.v1, l.i1};
    t[1] = {l.v2, l.i2};
    t[2] = {r.v1, r.i1};
    t[3] = {r.v2, r.i2};
    
    sort(t, t+4, cmp);
    
    u.v1 = t[0].x, u.i1 = t[0].y;
    for(int i = 1; i < 4; i++)
    {
        if(u.v1 != t[i].x)
        {
            u.v2 = t[i].x;
            u.i2 = t[i].y;
            break;
        }
    }
}
void pushup(int u)
{
    pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}
void build(int u, int l, int r)
{
    tr[u] = {l, r};
    
    if(l == r)
    {
        tr[u].v1 = a[l];
        tr[u].i1 = l;
    }
    else
    {
        int mid = l + r >> 1;
        build(u << 1, l, mid); build(u << 1 | 1, mid+1, r);
    
        pushup(u);
    }
}
void modify(int u, int x)
{
    if(tr[u].l == tr[u].r)
        tr[u] = {tr[u].l, tr[u].r};
    else
    {
        int mid = tr[u].l + tr[u].r >> 1;
        if(x <= mid) modify(u << 1, x);
        if(x > mid) modify(u << 1 | 1, x);
        pushup(u);
    }
}
node query(int u, int l, int r)
{
    if(l <= tr[u].l && tr[u].r <= r) return tr[u];
    else
    {
        node retv = {0};
        int mid = tr[u].l + tr[u].r >> 1;
        if(l <= mid) retv = query(u << 1, l, r);
        if(r > mid)
        {
            node qt = query(u << 1 | 1, l, r);
            pushup(retv, retv, qt);
        }
        return retv;
    }
}
int main()
{
    ios::sync_with_stdio(0); cin.tie(0);
    
    cin >> n >> k;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    
    build(1, 1, n);
    
    for(int i = 1; i <= n; i++)
    {
        node t = query(1, i, min(i+k, n));
        
        if(t.v1 != 0 && b[i-1] != t.v1)
        {
            b[i] = t.v1;
            modify(1, t.i1);
            k -= t.i1 - i;
        }
        else if(t.v2 != 0 && b[i-1] == t.v1)
        {
            b[i] = t.v2;
            modify(1, t.i2);
            k -= t.i2 - i;
        }
    }
    
    for(int i = 1; i <= n; i++)
        cout << (b[i] ? b[i] : -1) << ' ';
}

你可能感兴趣的:(蓝桥杯,算法)