玄关,75pts神奇RE+WA,甚至#1RE
查看原帖
玄关,75pts神奇RE+WA,甚至#1RE
470960
Yellow_and_Strong楼主2023/12/28 21:02

rt

#include <bits/stdc++.h>
#define int long long
#define INF 0x7fffffff

using namespace std;

const int MAXN = 1e5 + 10;

inline int read()
{
    int x = 0; char ch = getchar();
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch)) x = x * 10 + ch - 48, ch = getchar();
    return x;
}
inline void write (int x)
{
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) write(x / 10);
    putchar (x % 10 + 48);
}

int n, k, h[MAXN];
inline void input()
{
    n = read(), k = read();
    for (int i = 1; i <= n; ++ i) h[i] = read();
}

struct Tree
{
    Tree *ch[2];
    int siz, val, cnt, sum, rnd;
    Tree (int _val) : siz(1), val(_val), cnt(1), sum(_val) { ch[0] = ch[1] = NULL, rnd = rand(); }
    Tree (Tree *_Tree) { siz = _Tree->siz, val = _Tree->val, cnt = _Tree->cnt, sum = _Tree->sum, rnd = _Tree->rnd; }
    void upd()
    {
        siz = cnt, sum = val * cnt;
        if (ch[0] != NULL) siz += ch[0]->siz, sum += ch[0]->sum;
        if (ch[1] != NULL) siz += ch[1]->siz, sum += ch[1]->sum;
    }
}; Tree *root;
pair <Tree *, Tree *> Split_val (Tree *cur, int val)
{
    if (cur == NULL) return {NULL, NULL};
    if (cur->val <= val)
    {
        auto temp = Split_val(cur->ch[1], val);
        cur->ch[1] = temp.first, cur->upd();
        return {cur, temp.second};
    }
    else
    {
        auto temp = Split_val(cur->ch[0], val);
        cur->ch[0] = temp.second, cur->upd();
        return {temp.first, cur};
    }
}
tuple <Tree *, Tree *,  Tree *> Split_rnk (Tree *cur, int rnk)
{
    if (cur == NULL) return {NULL, NULL, NULL};
    int ls_siz = cur->ch[0] == NULL ? 0 : cur->ch[0]->siz;
    if (rnk <= ls_siz)
    {
        Tree *l, *mid, *r;
        tie(l, mid, r) = Split_rnk(cur->ch[0], rnk);
        cur->ch[0] = r, cur->upd();
        return {l, mid, cur};
    }
    else if (rnk <= ls_siz + cur->cnt)
    {
        Tree *l = cur->ch[0];
        Tree *r = cur->ch[1];
        cur->ch[0] = cur->ch[1] = NULL;
        return {l, cur, r};
    }
    else
    {
        Tree *l, *mid, *r;
        tie(l, mid, r) = Split_rnk(cur->ch[1], rnk - ls_siz - cur->cnt);
        cur->ch[1] = l, cur->upd();
        return {cur, mid, r};
    }
}
Tree *merge (Tree *x, Tree *y)
{
    if (x == NULL and y == NULL) return NULL;
    if (x != NULL and y == NULL) return x;
    if (x == NULL and y != NULL) return y;
    if (x->rnd < y->rnd)
        return x->ch[1] = merge(x->ch[1], y), x->upd(), x;
    else
        return y->ch[0] = merge(x, y->ch[0]), y->upd(), y;
}
inline void insert (int val)
{
    auto R = Split_val(root, val);
    auto L = Split_val(R.first, val - 1);
    Tree *_new;
    if (L.second == NULL) _new = new Tree(val);
    else ++ L.second->cnt, L.second->upd();
    Tree *_L = merge(L.first, L.second == NULL ? _new : L.second);
    root = merge(_L, R.second);
}
inline void del (int val)
{
    auto R = Split_val(root, val);
    auto L = Split_val(R.first, val - 1);
    if (L.second->cnt > 1)
        -- L.second->cnt, L.second->upd(), L.first = merge(L.first, L.second);
    else
    {
        if (R.first == L.second) R.first = NULL;
        delete L.second; L.second = NULL;
    }
    root = merge(L.first, R.second);
}
inline int Query_val (Tree *cur, int val)
{
    auto temp = Split_val(cur, val - 1);
    int ret = (temp.first == NULL ? 0 : temp.first->siz) + 1;
    return root = merge(temp.first, temp.second), ret;
}
inline int Query_rnk (Tree *cur, int rnk)
{
    Tree *l, *mid, *r;
    tie(l, mid, r) = Split_rnk(cur, rnk);
    int ret = mid->val;
    return root = merge(merge(l, mid), r), ret;
}
inline int Query_pre (int val)
{
    auto temp = Split_val(root, val - 1);
    int ret = Query_rnk(temp.first, temp.first->siz);
    return root = merge(temp.first, temp.second), ret;
}
inline int Query_sub (int val)
{
    auto temp = Split_val(root, val);
    int ret = Query_rnk(temp.second, 1);
    return root = merge(temp.first, temp.second), ret;
}

inline void init() { for(int i = 0; i < k; ++ i) insert(h[i]); }

int ans = INF, ans_l, ans_r, _ans;
inline void work()
{
    int l = 0, r = k - 1;
    while (r < n)
    {
        del(h[l ++]), insert(h[++ r]); int x;
        if (k & 1) x = Query_rnk(root, (k >> 1) + 1);
        else x = (Query_rnk(root, k >> 1) + Query_rnk(root, (k >> 1) + 1)) >> 1;
        auto R = Split_val(root, x);
        auto L = Split_val(R.first, x - 1);
        int suma = L.first->sum, numa = L.first->siz;
        int sumb = R.second->sum, numb = R.second->siz;
        root = merge(merge(L.first, L.second), R.second);
        int res = numa * x - suma + sumb - numb * x;
        if (res < ans) ans = res, ans_l = l, ans_r = r, _ans = x;
    }
}

inline void output()
{
    write(ans), putchar('\n');
    for (int i = 1; i < ans_l; ++ i)
        write(h[i]), putchar('\n');
    for (int i = ans_l; i <= ans_r; ++ i)
        write(_ans), putchar('\n');
    for (int i = ans_r + 1; i <= n; ++ i)
        write(h[i]), putchar('\n');
}

signed main()
{
    input();
    init();
    work();
    output();
    return 0;
}
2023/12/28 21:02
加载中...