题解:AT_joisc2016_h 回転寿司
前言
一道水的黑分块。
思路
观察到这个环可以拆成序列,只要将 但是我硬是卡过去了。
于是我们考虑对散块进行优化。由于每次整块进去的顺序都有先后,可以发现一个优化:我们将
:::success[code]
#include<bits/stdc++.h>
using namespace std;
static int n,m,a[400005],t,l[1005],r[1005],p[400005],siz;
static priority_queue<int>q[1005];
static priority_queue<int,vector<int>,greater<int> >tag[1005];
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<48||ch>57){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>=48&&ch<=57){
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*f;
}
inline int modify(const int x,const int y,int k){
if(p[x]==p[y]){
for(int i=l[p[x]];i<=r[p[y]];++i){
tag[p[x]].push(a[i]);
a[i]=tag[p[x]].top();
tag[p[x]].pop();
}
for(int i=l[p[x]];i<=r[p[y]];++i)q[p[x]].pop();
while(!tag[p[x]].empty())tag[p[x]].pop();
for(int i=x;i<=y;++i){
if(a[i]>k){
a[i]^=k^=a[i]^=k;
}
}
q[p[x]]=priority_queue<int>(a+l[p[x]],a+r[p[y]]+1);
}
else{
for(int i=l[p[x]];i<=r[p[x]];++i){
tag[p[x]].push(a[i]);
a[i]=tag[p[x]].top();
tag[p[x]].pop();
}
for(int i=l[p[x]];i<=r[p[x]];++i)q[p[x]].pop();
while(!tag[p[x]].empty())tag[p[x]].pop();
for(int i=x;i<=r[p[x]];++i){
if(a[i]>k){
a[i]^=k^=a[i]^=k;
}
}
q[p[x]]=priority_queue<int>(a+l[p[x]],a+r[p[x]]+1);
for(int i=p[x]+1;i<=p[y]-1;++i){
if(q[i].top()>k){
int v=q[i].top();
q[i].pop();
q[i].push(k);
tag[i].push(k);
k=v;
}
}
for(int i=l[p[y]];i<=r[p[y]];++i){
tag[p[y]].push(a[i]);
a[i]=tag[p[y]].top();
tag[p[y]].pop();
}
for(int i=l[p[y]];i<=r[p[y]];++i)q[p[y]].pop();
while(!tag[p[y]].empty())tag[p[y]].pop();
for(int i=l[p[y]];i<=y;++i){
if(a[i]>k){
a[i]^=k^=a[i]^=k;
}
}
q[p[y]]=priority_queue<int>(a+l[p[y]],a+r[p[y]]+1);
}
return k;
}
signed main(){
// freopen("P14400_1.in","r",stdin);
// freopen("P14400.out","w",stdout);
n=read(),m=read();
for(int i=1;i<=n;++i)a[i]=read();
t=sqrt(n)*0.6;
siz=n/t;
for(int i=1;i<=t;++i){
l[i]=(i-1)*siz+1;
r[i]=i*siz;
}
if(r[t]!=n){
t++;
l[t]=r[t-1]+1;
r[t]=n;
}
for(int i=1;i<=t;++i){
for(int j=l[i];j<=r[i];++j){
p[j]=i;
q[i].push(a[j]);
}
}
while(m--){
int x,y,k;
x=read(),y=read(),k=read();
if(x<=y){
cout<<modify(x,y,k)<<'\n';
}
else{
int v=modify(x,n,k);
cout<<modify(1,y,v)<<'\n';
}
}
return 0;
}
::::