「LibreOJ β Round」ZQC 的手办

https://loj.ac/problem/504

一类套路题.

首先这个玩意可以两个logn树套树做。。。。

naive地,把区间内的所有数拿出来放进堆里。不断取出。

太多了。

所以开始只保留那初始logn区间最小值,弹出之后再找出左右区间下一个

线段树维护最小值和最小值位置。

 

和超级钢琴,异或粽子,K个串都一样。

或者说k短路。

只不过这个是线段树载体。

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
    char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);}
template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}
namespace Modulo{
const int mod=998244353;
il int ad(int x,int y){return x+y>=mod?x+y-mod:x+y;}
il int sub(int x,int y){return ad(x,mod-y);}
il int mul(int x,int y){return (ll)x*y%mod;}
il void inc(int &x,int y){x=ad(x,y);}
il void inc2(int &x,int y){x=mul(x,y);}
il int qm(int x,int y=mod-2){int ret=1;while(y){if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;}
template<class ...Args>il int ad(const int a,const int b,const Args &...args) {return ad(ad(a,b),args...);}
template<class ...Args>il int mul(const int a,const int b,const Args &...args) {return mul(mul(a,b),args...);}
}
// using namespace Modulo;
namespace Miracle{
const int N=5e5+5;
const int inf=0x3f3f3f3f;
int n,m;
struct tr{
    int mi,p;
    int tag;
}t[4*N];
#define ls (x<<1)
#define rs (x<<1|1)
#define mid ((l+r)>>1)
void pushup(int x){
    t[x].mi=min(t[ls].mi,t[rs].mi);
    if(t[ls].mi==t[x].mi) t[x].p=t[ls].p;
    else t[x].p=t[rs].p;
}
void Max(int x,int c){
    t[x].mi=max(t[x].mi,c);
    t[x].tag=max(t[x].tag,c);
}
void pushdown(int x){
    if(t[x].tag){
        Max(ls,t[x].tag);
        Max(rs,t[x].tag);
        t[x].tag=0;
    }
}
int a[N];
void build(int x,int l,int r){
    if(l==r){
        t[x].mi=a[l];
        t[x].p=l;
        return;
    }
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(x);
}
void chan(int x,int l,int r,int L,int R,int c){
    if(L<=l&&r<=R){
        Max(x,c);
        return;
    }
    pushdown(x);
    if(L<=mid) chan(ls,l,mid,L,R,c);
    if(mid<R) chan(rs,mid+1,r,L,R,c);
    pushup(x);
}
pii query(int x,int l,int r,int L,int R){
    
    if(L<=l&&r<=R){
        return mk(t[x].p,t[x].mi);
    }
    pushdown(x);
    if(L>mid) return query(rs,mid+1,r,L,R);
    if(R<=mid) return query(ls,l,mid,L,R);
    pii le=query(ls,l,mid,L,R);
    pii ri=query(rs,mid+1,r,L,R);
    le.se=min(le.se,ri.se);
    if(ri.se==le.se) le.fi=ri.fi;
    return le;
}
struct po{
    int v,p,l,r;
    po(){}
    po(int vv,int pp,int le,int ri){
        v=vv;p=pp;l=le;r=ri;
    }
    bool friend operator <(po a,po b){
        return a.v>b.v;
    }
    void op(){
        cout<<" po "<<v<<" "<<p<<" "<<l<<" "<<r<<endl;
    }
};

priority_queue<po>q;
void push(int x,int l,int r,int L,int R,int k){
    if(L<=l&&r<=R){
        if(t[x].mi<k) q.push(po(t[x].mi,t[x].p,l,r));
        return;
    }
    pushdown(x);
    if(L<=mid) push(ls,l,mid,L,R,k);
    if(mid<R) push(rs,mid+1,r,L,R,k);
}

void clear(priority_queue<po>&q){
    priority_queue<po>tmp;
    q.swap(tmp);
}
int mem[5000000+4],num;
int main(){
    rd(n);
    for(reg i=1;i<=n;++i){
        rd(a[i]);
    }    
    build(1,1,n);
//    return 0;
    
    
    rd(m);
//    cout<<" 22223 "<<endl;
    int op,l,r,k,x;
    while(m--){
        rd(op);rd(l);rd(r);rd(k);
        if(op==1){
//            continue;
//            cout<<" op==1 "<<endl;
            chan(1,1,n,l,r,k);
        }else{
//            cout<<" op==2 "<<endl;
            rd(x);
            clear(q);
            push(1,1,n,l,r,k);
//            cout<<" size "<<q.size()<<endl;
            num=0;
            while(x&&!q.empty()){
                po now=q.top();q.pop();
//                now.op();
                if(now.v>=k) break;
                mem[++num]=now.v;
                if(now.l<=now.p-1){
//                    cout<<" findl "<<endl;
                    pii lp=query(1,1,n,now.l,now.p-1);
//                    cout<<" endq "<<endl;
                    q.push(po(lp.se,lp.fi,now.l,now.p-1));
//                    cout<<" enl "<<endl;
                }
                if(now.p+1<=now.r){
//                    cout<<" findr "<<endl;
                    pii lp=query(1,1,n,now.p+1,now.r);
                    q.push(po(lp.se,lp.fi,now.p+1,now.r));
//                    cout<<" enr "<<endl;
                }
                --x;
            }
            if(x){
                puts("-1");
            }else{
                prt(mem,1,num);
            }
        }
    }
    return 0;
}

}
signed main(){
//    freopen("data.in","r",stdin);
//    freopen("my.out","w",stdout);
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
*/
#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
    char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
    for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);}
template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}
namespace Modulo{
const int mod=998244353;
il int ad(int x,int y){return x+y>=mod?x+y-mod:x+y;}
il int sub(int x,int y){return ad(x,mod-y);}
il int mul(int x,int y){return (ll)x*y%mod;}
il void inc(int &x,int y){x=ad(x,y);}
il void inc2(int &x,int y){x=mul(x,y);}
il int qm(int x,int y=mod-2){int ret=1;while(y){if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;}
template<class ...Args>il int ad(const int a,const int b,const Args &...args) {return ad(ad(a,b),args...);}
template<class ...Args>il int mul(const int a,const int b,const Args &...args) {return mul(mul(a,b),args...);}
}
// using namespace Modulo;
namespace Miracle{
const int N=5e5+5;
const int inf=0x3f3f3f3f;
int n,m;
struct tr{
    int mi,p;
    int tag;
}t[4*N];
#define ls (x<<1)
#define rs (x<<1|1)
#define mid ((l+r)>>1)
void pushup(int x){
    t[x].mi=min(t[ls].mi,t[rs].mi);
    if(t[ls].mi==t[x].mi) t[x].p=t[ls].p;
    else t[x].p=t[rs].p;
}
void Max(int x,int c){
    t[x].mi=max(t[x].mi,c);
    t[x].tag=max(t[x].tag,c);
}
void pushdown(int x){
    if(t[x].tag){
        Max(ls,t[x].tag);
        Max(rs,t[x].tag);
        t[x].tag=0;
    }
}
int a[N];
void build(int x,int l,int r){
    if(l==r){
        t[x].mi=a[l];
        t[x].p=l;
        return;
    }
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(x);
}
void chan(int x,int l,int r,int L,int R,int c){
    if(L<=l&&r<=R){
        Max(x,c);
        return;
    }
    pushdown(x);
    if(L<=mid) chan(ls,l,mid,L,R,c);
    if(mid<R) chan(rs,mid+1,r,L,R,c);
    pushup(x);
}
pii query(int x,int l,int r,int L,int R){
    
    if(L<=l&&r<=R){
        return mk(t[x].p,t[x].mi);
    }
    pushdown(x);
    if(L>mid) return query(rs,mid+1,r,L,R);
    if(R<=mid) return query(ls,l,mid,L,R);
    pii le=query(ls,l,mid,L,R);
    pii ri=query(rs,mid+1,r,L,R);
    le.se=min(le.se,ri.se);
    if(ri.se==le.se) le.fi=ri.fi;
    return le;
}
struct po{
    int v,p,l,r;
    po(){}
    po(int vv,int pp,int le,int ri){
        v=vv;p=pp;l=le;r=ri;
    }
    bool friend operator <(po a,po b){
        return a.v>b.v;
    }
    void op(){
        cout<<" po "<<v<<" "<<p<<" "<<l<<" "<<r<<endl;
    }
};

priority_queue<po>q;
void push(int x,int l,int r,int L,int R,int k){
    if(L<=l&&r<=R){
        if(t[x].mi<k) q.push(po(t[x].mi,t[x].p,l,r));
        return;
    }
    pushdown(x);
    if(L<=mid) push(ls,l,mid,L,R,k);
    if(mid<R) push(rs,mid+1,r,L,R,k);
}

void clear(priority_queue<po>&q){
    priority_queue<po>tmp;
    q.swap(tmp);
}
int mem[5000000+4],num;
int main(){
    rd(n);
    for(reg i=1;i<=n;++i){
        rd(a[i]);
    }    
    build(1,1,n);
//    return 0;
    
    
    rd(m);
//    cout<<" 22223 "<<endl;
    int op,l,r,k,x;
    while(m--){
        rd(op);rd(l);rd(r);rd(k);
        if(op==1){
//            continue;
//            cout<<" op==1 "<<endl;
            chan(1,1,n,l,r,k);
        }else{
//            cout<<" op==2 "<<endl;
            rd(x);
            clear(q);
            push(1,1,n,l,r,k);
//            cout<<" size "<<q.size()<<endl;
            num=0;
            while(x&&!q.empty()){
                po now=q.top();q.pop();
//                now.op();
                if(now.v>=k) break;
                mem[++num]=now.v;
                if(now.l<=now.p-1){
//                    cout<<" findl "<<endl;
                    pii lp=query(1,1,n,now.l,now.p-1);
//                    cout<<" endq "<<endl;
                    q.push(po(lp.se,lp.fi,now.l,now.p-1));
//                    cout<<" enl "<<endl;
                }
                if(now.p+1<=now.r){
//                    cout<<" findr "<<endl;
                    pii lp=query(1,1,n,now.p+1,now.r);
                    q.push(po(lp.se,lp.fi,now.p+1,now.r));
//                    cout<<" enr "<<endl;
                }
                --x;
            }
            if(x){
                puts("-1");
            }else{
                prt(mem,1,num);
            }
        }
    }
    return 0;
}

}
signed main(){
//    freopen("data.in","r",stdin);
//    freopen("my.out","w",stdout);
    Miracle::main();
    return 0;
}

/*
   Author: *Miracle*
*/

 

上一篇:C++ 各种排序算法总结


下一篇:初步认识RSA加密