题意
维护成环的序列 (a):
- 给定 (A),
for i in [l..r]: if a[i]>A: swap(a[i],A)
,询问 (A) 最后的值。
询问之间显然不独立。
(nleq 4 imes 10^5),(mleq 2.5 imes 10^4),9s。
题解
分块,对于每一块,用一大根堆维护其内部所有的值,用一小根堆维护其 tag。
- 整块修改:pop 掉最大值,用 (A) 来替换;并将 (A) 扔进 tag;
- 重构:从左到右扫过去,尝试用 tag 的堆顶更新 (a_i)。
#include<bits/stdc++.h>
using namespace std;
int getint(){
int ans=0;
char c=getchar();
while(c<'0'||c>'9')c=getchar();
while(c>='0'&&c<='9'){
ans=ans*10+c-'0';
c=getchar();
}
return ans;
}
const int N=4e5+10,B=700;
int a[N];
int blk,bl[N];
int n,m;
struct block{
int l,r;
priority_queue<int>val;
priority_queue<int,vector<int>,greater<int>>tag;
block():l(0x3f3f3f3f){}
void rebuild(){
// while(val.size())val.pop();
if(tag.empty())return;
for(int i=l;i<=r;i++){
if(a[i]>tag.top()){
int t=tag.top();tag.pop();
tag.push(a[i]);
a[i]=t;
}
}
}
int run(int x){
tag.push(x);
val.push(x);
int t=val.top();
val.pop();
return t;
}
int run(int l,int r,int x){
rebuild();
for(int i=l;i<=r;i++)if(a[i]>x)swap(a[i],x);
// for(int i=this->l;i<=this->r;i++)val.push(a[i]);
return x;
}
};
block b[B];
int main(){
n=getint(),m=getint();
blk=sqrt(n);
int bc=n/blk+1;
for(int i=1;i<=n;i++)bl[i]=i/blk,
b[bl[i]].l=min(b[bl[i]].l,i),
b[bl[i]].r=max(b[bl[i]].r,i);
for(int i=1;i<=n;i++){
a[i]=getint();
b[bl[i]].val.push(a[i]);
}
while(m--){
int l=getint(),r=getint(),a=getint();
if(bl[l]==bl[r]&&l<=r){
a=b[bl[l]].run(l,r,a);
printf("%d
",a);
}else{
int lb=(bl[l]+1)%bc,rb=bl[r];
a=b[bl[l]].run(l,b[bl[l]].r,a);
while(lb!=rb){
a=b[lb].run(a);
lb=(lb+1)%bc;
}
a=b[bl[r]].run(b[bl[r]].l,r,a);
printf("%d
",a);
}
}
}