Codeforces 1326 E. Bombs (Line Segment Tree)

Link to the
topic The main idea of ​​the topic:
a sequence p and a sequence q. Press p1p2 ... pn to place the bomb above the 1,2, ... n position, each bomb has a value, then the sequence of q is that there is already a bomb at the current qi position, if there is already a bomb, then put The maximum value of the currently released (including the currently released) is removed, and finally the maximum value of the remaining bombs is output. Ask about the prefix of each qi.
Problem-solving ideas:
It is easy to see that the longer the prefix, the greater the number of deletions, so the answer must be non-increasing.
According to the solution, assuming that the current answer is x-1, all bombs with ≥ x must be cleared, and a bomb needs to be cleared with a qi ≥ current position. So suppose an array b, b [i] represents the number of ≥x in the suffix of [i… n]-the number of bombs already in [i…, n], when all b [i] ≤ 0 This means that bombs with ≥ x have been cleared. It is enough to maintain the query t [1] with the maximum value of the line segment tree.
Then first insert [1 ... pos [n]] into the segment tree, and then each time a q [i] is encountered, the value of [1 ... q [i]] is -1, if the current t [1]> 0 It means that the current value has not been cleared and output directly, otherwise the answer ans– will be added, and the value of [1… pos [ans]] will be +1 after each decrement until t [1]> 0 means ≥ans The bomb was not completely cleared, that is the answer.

#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;
}
Published 12 original articles · Like1 · Visits 327

Guess you like

Origin blog.csdn.net/qq_41818939/article/details/105036578