BZOJ 4552: [Tjoi2016 & Heoi2016] sort binary sort answer segment tree 01

title

BZOJ 4552

LUOGU 2824

Meaning of the questions:

Gives a \ (1 \ sim n \) of the full array, now the full array sequence \ (m \) topical, the sort divided into two types:

  1. 0,l,rShows a section \ ([l, r] \ ) in ascending numerical order;

  2. 1,l,rShows a section \ ([l, r] \ ) digital descending order;

Finally, ask the first \ (q \) numbers on the position.

analysis

Meaning of the questions simple and clear, if this sequence is converted into \ (01 \) sequence, then you should do a lot better than the original sequence.

Because you can use \ (O (\ log n) \) the algorithm \ (01 \) sequence ordering, we use the tree line to maintain.

The query interval period \ (1 \) number referred to as \ (NUM \) , if it is ascending, this section will \ ([r-num + 1 , r] \) are changed to \ (1 \) , the \ ([l, r-num ] \) is changed to \ (0 \) . Descending then \ ([l, l + num -1] \) is changed to \ (1 \) , the \ ([l num, r + ] \) is changed to \ (0 \) . (Note: \ (num = 0 \) , the directly \ ([l, r] \ ) is changed to \ (0 \) , to avoid \ (L> R \) caused \ (REs \) ).

So that we successfully converted to sort and query range interval modification.

This question then for it, sweep it again definitely hung up, it would be half the answer.

Of course, in this case, it can only be done offline.

Binary answer \ (MID \) , the original sequence \ (\ geqslant m \) has been changed to \ (1 \) , the original sequence \ (<m \) has been changed to \ (0 \) , for each operation, the \ (01 \) sequence sort (that is said above tree line \ (01 \) sorting), if \ (q \) position or \ (1 \) , then the answer is feasible .

And binary value established if and only if the value of the position \ (\ geqslant m \) , so if \ (Check \) Returns \ (to true \) , then \ (L = MID +. 1 \) , or \ (R & lt . 1-MID = \) .

code

#include<bits/stdc++.h>

const int maxn=1e5+10;

namespace IO
{
    char buf[1<<15],*fs,*ft;
    inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
    template<typename T>inline void read(T &x)
    {
        x=0;
        T f=1, ch=getchar();
        while (!isdigit(ch) && ch^'-') ch=getchar();
        if (ch=='-') f=-1, ch=getchar();
        while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
        x*=f;
    }

    char Out[1<<24],*fe=Out;
    inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }
    template<typename T>inline void write(T x,char str)
    {
        if (!x) *fe++=48;
        if (x<0) *fe++='-', x=-x;
        T num=0, ch[20];
        while (x) ch[++num]=x%10+48, x/=10;
        while (num) *fe++=ch[num--];
        *fe++=str;
    }
}

using IO::read;
using IO::write;

int a[maxn];
namespace SGT
{
    int tree[maxn<<2],atag[maxn<<2];
    inline void build(int x,int l,int r,int k)
    {
        if (l==r)
        {
            tree[x]=a[l]>=k;
            atag[x]=0;
            return ;
        }
        int mid=(l+r)>>1;
        build(x<<1,l,mid,k);
        build(x<<1|1,mid+1,r,k);
        tree[x]=tree[x<<1]+tree[x<<1|1];
        atag[x]=0;
    }

    inline void pushdown(int x,int l,int r)
    {
        int mid=(l+r)>>1;
        if (atag[x]==1) tree[x<<1]=mid-l+1, tree[x<<1|1]=r-mid;
        else tree[x<<1]=tree[x<<1|1]=0;
        atag[x<<1]=atag[x<<1|1]=atag[x];
        atag[x]=0;
    }

    inline void Change(int x,int l,int r,int tl,int tr,int k)
    {
        if (tl>r || l>tr) return ;
        if (tl<=l && r<=tr)
        {
            tree[x]=k*(r-l+1);
            atag[x]=k ? 1 : -1;
            return ;
        }
        if (atag[x]) pushdown(x,l,r);
        int mid=(l+r)>>1;
        Change(x<<1,l,mid,tl,tr,k);
        Change(x<<1|1,mid+1,r,tl,tr,k);
        tree[x]=tree[x<<1]+tree[x<<1|1];
    }

    inline int query(int x,int l,int r,int tl,int tr)
    {
        if (tl>r || l>tr) return 0;
        if (tl<=l && r<=tr) return tree[x];
        if (atag[x]) pushdown(x,l,r);
        int mid=(l+r)>>1;
        return query(x<<1,l,mid,tl,tr)+query(x<<1|1,mid+1,r,tl,tr);
    }

    inline int queryPoint(int x,int l,int r,int k)
    {
        if (l==k && k==r) return tree[x];
        if (atag[x]) pushdown(x,l,r);
        int mid=(l+r)>>1;
        if (k<=mid) return queryPoint(x<<1,l,mid,k);
        else return queryPoint(x<<1|1,mid+1,r,k);
    }
}

using SGT::build;
using SGT::query;
using SGT::Change;
using SGT::queryPoint;

int n,m,q;
int opt[maxn],L[maxn],R[maxn];
inline bool check(int x)
{
    build(1,1,n,x);
    for (int i=1; i<=m; ++i)
    {
        int num=query(1,1,n,L[i],R[i]);
        if (!num) { Change(1,1,n,L[i],R[i],0); continue; }//避免出现 L>R 的情况
        if (!opt[i]) Change(1,1,n,R[i]-num+1,R[i],1), Change(1,1,n,L[i],R[i]-num,0);
        else Change(1,1,n,L[i],L[i]+num-1,1), Change(1,1,n,L[i]+num,R[i],0);
    }
    return queryPoint(1,1,n,q);
}

int main()
{
    read(n);read(m);
    for (int i=1; i<=n; ++i) read(a[i]);
    for (int i=1; i<=m; ++i) read(opt[i]),read(L[i]),read(R[i]);
    read(q);
    int l=1, r=n, ans=0;
    while (l<=r)
    {
        int mid=(l+r)>>1;
        if (check(mid)) ans=mid, l=mid+1;
        else r=mid-1;
    }
    write(ans,'\n');
    IO::flush();
    return 0;
}

Guess you like

Origin www.cnblogs.com/G-hsm/p/11482149.html