蒟蒻求助被卡常
查看原帖
蒟蒻求助被卡常
366455
西湖水妖楼主2022/8/16 16:09

rt。TLE 最后一个点。代码风格很毒瘤,其中线段树部分时,修改、操作的左右边界定义、操作的值在外面, LR 分别左右边界,v 是操作的值,边界是左闭右开。是不是很毒瘤。

#include <bits/stdc++.h>
using namespace std;

char ch;
void read(unsigned &x)
{
    x = 0u;
    do
        ch = getchar();
    while(isspace(ch));
    while(isdigit(ch))
    {
        x *= 10u;
        x += ch;
        x -= '0';
        ch = getchar();
    }
}

unsigned n, m, C, L, R;
unsigned long long v;
array<unsigned, 1000000> a, rk;
vector<unsigned> b;
array<unsigned, 4000000> l, r, rr, mid, cnt;
array<unsigned long long, 4000000> mi, add, cov;

void pushup(const unsigned &u)
{
    mi[u] = min(mi[u << 1u], mi[u << 1u | 1u]);
}
void build(const unsigned &u, const unsigned &L, const unsigned &R)
{
    l[u] = L;
    r[u] = R;
    rr[u] = R - 1u;
    mid[u] = L + R >> 1u;
    cov[u] = - 1u;
    if(L == rr[u])
        return;
    build(u << 1u, L, mid[u]);
    build(u << 1u | 1u, mid[u], R);
}
void Add(const unsigned &u, const unsigned long long &v)
{
    mi[u] += v;
    add[u] += v;
}
void Addb(const unsigned &u, const unsigned &c)
{
    mi[u] += static_cast<unsigned long long>(c) * b[rr[u]];
    cnt[u] += c;
}
void Cov(const unsigned &u, const unsigned long long &v)
{
    mi[u] = v;
    add[u] = 0ull;
    cnt[u] = 0u;
    cov[u] = v;
}
void pushdown(const unsigned &u)
{
    if(cov[u] != - 1u)
    {
        Cov(u << 1u, cov[u]);
        Cov(u << 1u | 1u, cov[u]);
        cov[u] = - 1u;
    }
    if(cnt[u])
    {
        Addb(u << 1u, cnt[u]);
        Addb(u << 1u | 1u, cnt[u]);
        cnt[u] = 0u;
    }
    if(add[u])
    {
        Add(u << 1u, add[u]);
        Add(u << 1u | 1u, add[u]);
        add[u] = 0u;
    }
}
void change_add(const unsigned &u)
{
    if(L <= l[u] && r[u] <= R)
    {
        Add(u, v);
        return;
    }
    pushdown(u);
    if(L < mid[u])
        change_add(u << 1u);
    if(R > mid[u])
        change_add(u << 1u | 1u);
    pushup(u);
}
void change_addb(const unsigned &u)
{
    if(L <= l[u] && r[u] <= R)
    {
        Addb(u, 1u);
        return;
    }
    pushdown(u);
    if(L < mid[u])
        change_addb(u << 1u);
    if(R > mid[u])
        change_addb(u << 1u | 1u);
    pushup(u);
}
void change_cov(const unsigned &u)
{
    if(L <= l[u] && r[u] <= R)
    {
        Cov(u, v);
        return;
    }
    pushdown(u);
    if(L < mid[u])
        change_cov(u << 1u);
    if(R > mid[u])
        change_cov(u << 1u | 1u);
    pushup(u);
}
unsigned long long query_v(const unsigned &u)
{
    if(l[u] == rr[u])
        return mi[u];
    pushdown(u);
    if(L < mid[u])
        return query_v(u << 1u);
    return query_v(u << 1u | 1u);
}
unsigned query_clower(const unsigned &u)
{
    if(l[u] == rr[u])
        return l[u];
    pushdown(u);
    if(mi[u << 1u] <= v)
        return query_clower(u << 1u);
    return query_clower(u << 1u | 1u);
}
unsigned query_lower(const unsigned &u)
{
    if(L <= l[u])
        if(mi[u] <= v)
            return query_clower(u);
        else
            return 0u;
    pushdown(u);
    unsigned ans;
    if(L < mid[u])
    {
        ans = query_lower(u << 1u);
        if(ans)
            return ans;
    }
    return query_lower(u << 1u | 1u);
}

int main()
{
    read(n);
    b.reserve(n);
    read(C);
    auto E(a.begin() + n);
    for(auto i(a.begin()); i != E; ++ i)
    {
        read(*i);
        b.push_back(*i);
    }
    sort(b.begin(), b.end());
    b.erase(unique(b.begin(), b.end()), b.end());
    m = b.size();
    auto bB(b.begin()), bE(b.end());
    for(unsigned i(0u); i != n; ++ i)
        rk[i] = bE - lower_bound(bB, bE, a[i]) - 1u;
    reverse(bB, bE);
    build(1u, 0u, m);
    for(unsigned i(0u); i != n; ++ i)
    {
        L = rk[i] + 1u;
        R = m;
        v = C;
        if(L < R)
            change_add(1u);
        L = 0u;
        R = rk[i];
        v = - static_cast<unsigned long long>(a[i]);
        if(L < R)
        {
            change_addb(1u);
            change_add(1u);
        }
        L = rk[i];
        v = query_v(1u);
        ++ L;
        if(L < m)
            R = query_lower(1u);
        if(! R)
            R = m;
        if(L < R)
            change_cov(1u);
    }
    cout << mi[1];
    return 0;
}
2022/8/16 16:09
加载中...