LOJ#504. 「LibreOJ β Round」ZQC 的手办 线段树+堆
由于只有取 max 标记,所以直接在线段树上维护就行.
然后取前 k 大的话就用一个堆来维护四元组 $(l,r,v,pos)$ 表示区间 $[l,r]$ 的最小值为 $v$ ,位置为 pos.
查询的时候按照 $v$ 递增的顺序取出堆顶,然后按照 pos 分裂,再扔回堆里就行了.
code:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#define N 500009
#define lson now<<1
#define rson now<<1|1
#define inf 2000000000
#define setIO(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
using namespace std;
int n,m;
int a[N],lazy[N<<2];
struct data {
int pos,v;
data(int x=0,int y=inf) { pos=x,v=y; }
data operator+(const data b) const {
data c;
if(v<b.v) {
c.pos=pos,c.v=v;
}
else {
c.pos=b.pos,c.v=b.v;
}
return c;
}
}s[N<<2];
struct node {
int l,r,v,pos;
node(int l=0,int r=0,int v=0,int pos=0):l(l),r(r),v(v),pos(pos){}
bool operator<(const node b) const {
return v>b.v;
}
};
priority_queue<node>q;
void build(int l,int r,int now) {
if(l==r) {
s[now]=data(l,a[l]);
return;
}
int mid=(l+r)>>1;
build(l,mid,lson),build(mid+1,r,rson);
s[now]=s[lson]+s[rson];
}
void mark(int now,int v) {
lazy[now]=max(lazy[now],v);
s[now].v=max(s[now].v,v);
}
void pushdown(int now) {
if(lazy[now]) {
mark(lson,lazy[now]);
mark(rson,lazy[now]);
lazy[now]=0;
}
}
void update(int l,int r,int now,int L,int R,int v) {
if(l>=L&&r<=R) {
mark(now,v);
return;
}
int mid=(l+r)>>1;
pushdown(now);
if(L<=mid) update(l,mid,lson,L,R,v);
if(R>mid) update(mid+1,r,rson,L,R,v);
s[now]=s[lson]+s[rson];
}
data query(int l,int r,int now,int L,int R) {
if(l>=L&&r<=R)
return s[now];
int mid=(l+r)>>1;
pushdown(now);
if(L<=mid&&R>mid) return query(l,mid,lson,L,R)+query(mid+1,r,rson,L,R);
else if(L<=mid) return query(l,mid,lson,L,R);
else return query(mid+1,r,rson,L,R);
}
int an[N],top;
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {
int x=0; char c;
do {
c=nc();
}while(c<48);
while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc();
return x;
}
int main() {
// setIO("input");
node e;
data tmp;
int x,y,z,op,k;
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
build(1,n,1);
scanf("%d",&m);
for(int i=1;i<=m;++i) {
scanf("%d",&op);
if(op==1) {
scanf("%d%d%d",&x,&y,&k);
update(1,n,1,x,y,k);
}
else {
scanf("%d%d%d%d",&x,&y,&z,&k);
top=0;
tmp=query(1,n,1,x,y);
q.push(node(x,y,tmp.v,tmp.pos));
for(int j=1;j<=k;++j) {
if(q.empty()) break;
if(q.top().v>=z) break;
e=q.top(),q.pop();
an[++top]=e.v;
if(e.pos>e.l) {
tmp=query(1,n,1,e.l,e.pos-1);
q.push(node(e.l,e.pos-1,tmp.v,tmp.pos));
}
if(e.r>e.pos) {
tmp=query(1,n,1,e.pos+1,e.r);
q.push(node(e.pos+1,e.r,tmp.v,tmp.pos));
}
}
while(!q.empty()) q.pop();
if(top==k) {
for(int j=1;j<=top;++j) printf("%d ",an[j]);
printf("\n");
}
else printf("-1\n");
}
}
return 0;
}

浙公网安备 33010602011771号