区间对一个数取max。
区间求最小的x个比k小的数。
第一个操作很好搞。
第二个操作有个很显然的常数大做法。
实际上可以用堆把这个区间的笛卡尔树按优先级广搜。
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
const int maxn=500000+10,inf=1000000000;
struct dong{
int x,y;
friend bool operator <(dong a,dong b){
return a.xx||a.x==b.x&&a.yy;
}
friend dong operator +(dong a,dong b){
if (areturn a;else return b;
}
} tmp;
struct suan{
int l,r,p,v;
friend bool operator <(suan a,suan b){
return a.v>b.v||a.v==b.v&&a.p dl;
dong tree[maxn*4];
int mx[maxn*4],a[maxn],ans[maxn],sta[80];
bool bz[maxn*4];
int i,j,k,l,r,p,t,n,m,tot,top;
int read(){
int x=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9'){
if (ch=='-') f=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9'){
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
void build(int p,int l,int r){
if (l==r){
tree[p].x=a[l];
tree[p].y=l;
return;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
tree[p]=tree[p*2]+tree[p*2+1];
}
void mark(int p,int v){
bz[p]=1;
mx[p]=max(mx[p],v);
if (tree[p].xx=v;
}
void down(int p){
if (bz[p]){
mark(p*2,mx[p]);
mark(p*2+1,mx[p]);
bz[p]=0;
}
}
void change(int p,int l,int r,int a,int b,int v){
if (l==a&&r==b){
mark(p,v);
return;
}
down(p);
int mid=(l+r)/2;
if (b<=mid) change(p*2,l,mid,a,b,v);
else if (a>mid) change(p*2+1,mid+1,r,a,b,v);
else change(p*2,l,mid,a,mid,v),change(p*2+1,mid+1,r,mid+1,b,v);
tree[p]=tree[p*2]+tree[p*2+1];
}
void query(int p,int l,int r,int a,int b){
if (l==a&&r==b){
tmp=tmp+tree[p];
return;
}
down(p);
int mid=(l+r)/2;
if (b<=mid) query(p*2,l,mid,a,b);
else if (a>mid) query(p*2+1,mid+1,r,a,b);
else query(p*2,l,mid,a,mid),query(p*2+1,mid+1,r,mid+1,b);
}
int main(){
n=read();
fo(i,1,n) a[i]=read();
build(1,1,n);
m=read();
fo(i,1,m){
t=read();
if (t==1){
l=read();r=read();k=read();
change(1,1,n,l,r,k);
}
else{
l=read();r=read();k=read();j=read();
if (r-l+1printf("-1\n");
continue;
}
while (!dl.empty()) dl.pop();
zlt.l=l;zlt.r=r;
tmp.x=inf;
query(1,1,n,l,r);
zlt.p=tmp.y;zlt.v=tmp.x;
dl.push(zlt);
tot=0;
while (j--){
zlt=dl.top();
dl.pop();
if (zlt.v>=k) break;
ans[++tot]=zlt.v;
l=zlt.l;r=zlt.r;p=zlt.p;
if (l1;
tmp.x=inf;
query(1,1,n,l,p-1);
zlt.p=tmp.y;zlt.v=tmp.x;
dl.push(zlt);
}
if (p1;
zlt.r=r;
tmp.x=inf;
query(1,1,n,p+1,r);
zlt.p=tmp.y;zlt.v=tmp.x;
dl.push(zlt);
}
}
if (j>=0) printf("-1\n");
else{
fo(j,1,tot) printf("%d ",ans[j]);
printf("\n");
}
}
}
}