Codeforces 1326 E. Bombas (Árvore de segmentos de linha)

Link para o
tópico A idéia principal do tópico:
uma sequência pe uma sequência q. Pressione p1p2 ... pn para colocar a bomba acima da posição 1,2, ... n, cada bomba tem um valor, então a sequência de q é que já existe uma bomba na posição qi atual, se já houver uma bomba, coloque O valor máximo das bombas atualmente liberadas (incluindo as liberadas atualmente) é removido e, finalmente, o valor máximo das bombas restantes é emitido. Pergunte sobre o prefixo de cada qi.
Idéias para a solução de problemas:
é fácil ver que quanto maior o prefixo, maior o número de exclusões, portanto a resposta deve não aumentar.
De acordo com a solução, assumindo que a resposta atual seja x-1, todas as bombas com ≥ x devem ser limpas e uma bomba precisa ser limpa com uma posição atual qi ≥. Então, suponha que uma matriz b, b [i] represente o número de ≥x no sufixo de [i… n] - o número de bombas já em [i…, n], quando todas as b [i] ≤ 0 Isso significa que bombas com ≥ x foram apagadas. É suficiente manter a consulta t [1] com o valor máximo da árvore de segmentos de linha.
Em seguida, insira primeiro [1 ... pos [n]] na árvore de segmentos e, sempre que um q [i] for encontrado, o valor de [1 ... q [i]] será -1, se o atual t [1]> 0 Isso significa que o valor atual não foi apagado e emitido diretamente, caso contrário, a resposta ans– será adicionada e o valor de [1… pos [ans]] será +1 após cada decremento, até que t [1]> 0 signifique ≥ans A bomba não foi completamente limpa, eis a resposta.

#include<bits/stdc++.h>
using namespace std;
mt19937 rng_32(chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
const int maxn=3e5+10;
int t[maxn<<2],lz[maxn<<2];
void pushup(int i)
{
    t[i]=max(t[i<<1],t[i<<1|1]);
}
void pushdown(int i)
{
    if (lz[i])
    {
        t[i<<1]+=lz[i];
        lz[i<<1]+=lz[i];
        t[i<<1|1]+=lz[i];
        lz[i<<1|1]+=lz[i];
        lz[i]=0;
    }
}
void update(int l,int r,int i,int ql,int qr,int add)
{
    if (ql<=l && qr>=r)
    {
        t[i]+=add;
        lz[i]+=add;
        return ;
    }
    pushdown(i);
    int mid=(l+r)>>1;
    if (ql<=mid)
    update(l,mid,i<<1,ql,qr,add);
    if (qr>mid)
    update(mid+1,r,i<<1|1,ql,qr,add);
    pushup(i);
}
int a[maxn],b[maxn];
int pos[maxn];
int main()
{
    int n;
    cin>>n;
    for (int i=1;i<=n;i++)
    {
        cin>>a[i];
        pos[a[i]]=i;
    }
    for (int i=1;i<=n;i++)
    cin>>b[i];
    int ans=n;
    update(1,n,1,1,pos[n],1);
    cout<<n<<" ";
    for(int i=1;i<n;i++)
    {
        update(1,n,1,1,b[i],-1);
        if (t[1]>0)
        {
            cout<<ans<<" ";
        }
        else
        {
            while (t[1]<=0)
            {
                ans--;
                update(1,n,1,1,pos[ans],1);
            }
            cout<<ans<<" ";
        }
    }
    return 0;
}
Publicado 12 artigos originais · Gosto1 · Visitas 327

Acho que você gosta

Origin blog.csdn.net/qq_41818939/article/details/105036578
Recomendado
Clasificación