社区讨论

萌新刚学1msOI求卡常

P8078[WC2022] 秃子酋长参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mhz4f13e
此快照首次捕获于
2025/11/15 01:17
4 个月前
此快照最后确认于
2025/11/16 13:55
4 个月前
查看原帖
TLE on #17
CPP
#include <bits/stdc++.h>
using namespace std;

namespace IO
{
    char ch;
    inline void read() {}
    template<class T1, class... T2>
    inline void read(T1& num1, T2&... num2)
    {
        num1 = 0; ch = getchar();
        for (; !isdigit(ch); ch = getchar());
        for (; isdigit(ch); ch = getchar())
            num1 = num1 * 10 + (ch ^ '0');
        read(num2...);
    }
}
using IO::read;

typedef long long ll;

const int N = 5e5 + 5;
const int Q = 5e5 + 5;
//const int B = 500;
int B;

int n, q, a[N], pos[N];
int bl[N], br[N], bid[N], m;

ll ans[N], crt, bck;
int bckl, bckr, l, r;

struct listnode
{
    int prev, next;
}arr[N];

int top;
struct history
{
    int node; listnode val;
}stk[N];

struct operation
{
    int l, r, id;
    bool operator<(const operation& mem) const
    {
        if (bid[l] != bid[mem.l])
            return bid[l] < bid[mem.l];
        return r > mem.r;
    }
}oper[N];

inline void erase(int x)
{
    stk[++top] = {x, arr[x]};
    if (arr[x].prev)
    {
        crt -= abs(pos[x] - pos[arr[x].prev]);
        arr[arr[x].prev].next = arr[x].next;
    }
    if (arr[x].next)
    {
        crt -= abs(pos[x] - pos[arr[x].next]);
        arr[arr[x].next].prev = arr[x].prev;
    }
    if (arr[x].prev && arr[x].next)
    {
        crt += abs(pos[arr[x].prev] - pos[arr[x].next]);
    }
}

inline void brute(int l, int r)
{
    bck = 0;
    bckl = l; bckr = r;
    for (int i = 1; i <= n; ++i)
    {
        arr[i].prev = i - 1;
        arr[i].next = i + 1;
        bck += abs(pos[i] - pos[i + 1]);
    }
    bck -= abs(pos[n] - pos[n + 1]);
    arr[1].prev = arr[n].next = 0;
    crt = bck;
    for (int i = 1; i < l; ++i)
    {
        erase(a[i]);
    }
    for (int i = r + 1; i <= n; ++i)
    {
        erase(a[i]);
    }
    bck = crt;
    top = 0;
}

inline void backup()
{
    top = 0; bck = crt;
    bckl = l; bckr = r;
}

inline void recover()
{
    int x;
    crt = bck;
    l = bckl; r = bckr;
    while (top)
    {
        arr[x = stk[top].node] = stk[top].val;
        arr[arr[x].prev].next = x;
        arr[arr[x].next].prev = x;
        --top;
    }
}

int main()
{
    read(n, q); B = sqrt(n);
    for (int i = 1; i <= n; ++i)
    {
        read(a[i]);
        bid[i] = (i - 1) / B + 1;
        pos[a[i]] = i;
    }
    m = bid[n];
    for (int i = 1; i <= m; ++i)
    {
        bl[i] = br[i - 1] + 1;
        br[i] = br[i - 1] + B;
    }
    br[m] = n;
    for (int i = 1; i <= q; ++i)
    {
        read(l, r);
        oper[i] = {l, r, i};
    }
    sort(oper + 1, oper + 1 + q);
    for (int i = 1; i <= q; ++i)
    {
        if (bid[oper[i].l] != bid[oper[i - 1].l])
            brute(bl[bid[oper[i].l]], oper[i].r);

        recover();

        while (r > oper[i].r)
            erase(a[r--]);

        backup();

        while (l < oper[i].l)
            erase(a[l++]);

        ans[oper[i].id] = crt;
    }
    for (int i = 1; i <= q; ++i)
    {
        printf("%lld\n", ans[i]);
    }
    return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...