AOJ 1508: RMQ
いかにもJOIerが得意そうな問題。
高校生に戻った気分になって書いてみた。
平方分割すればよい。実装時間20分。
#include<stdio.h> #include<algorithm> #include<vector> using namespace std; int SQ=400; struct wolf{ vector<int>v; int m; wolf(){ v.clear(); m=99999999; } }; vector<wolf>li; int tmp[210000]; int c[210000]; int main(){ int a,b; scanf("%d%d",&a,&b); for(int i=0;i<a;i++)scanf("%d",c+i); wolf now; for(int i=0;i<a;i++){ now.v.push_back(c[i]); now.m=min(now.m,c[i]); if(i%SQ==SQ-1){li.push_back(now);now=wolf();} } if(now.v.size())li.push_back(now); for(int i=0;i<b;i++){ int p,q,r;scanf("%d%d%d",&p,&q,&r); if(p==0){ int at=0; int me=0; for(int j=0;j<li.size();j++){ if(at<=r&&r<at+li[j].v.size()){ int ind=r-at; me=li[j].v[ind]; for(int k=ind+1;k<li[j].v.size();k++){ li[j].v[k-1]=li[j].v[k]; } li[j].v.pop_back(); li[j].m=99999999; for(int k=0;k<li[j].v.size();k++) li[j].m=min(li[j].m,li[j].v[k]); break; } at+=li[j].v.size(); } at=0; for(int j=0;j<li.size();j++){ if(at<=q&&q<at+li[j].v.size()){ int ind=q-at; li[j].v.push_back(0); for(int k=li[j].v.size()-1;k>ind;k--){ li[j].v[k]=li[j].v[k-1]; } li[j].v[ind]=me; li[j].m=99999999; for(int k=0;k<li[j].v.size();k++) li[j].m=min(li[j].m,li[j].v[k]); break; } at+=li[j].v.size(); } } if(p==1){ int at=0; int ret=99999999; for(int j=0;j<li.size();j++){ if(q<=at&&at+li[j].v.size()<=r+1)ret=min(ret,li[j].m); else if(!(at+li[j].v.size()<=q||r<at)){ for(int k=0;k<li[j].v.size();k++){ if(q<=at+k&&at+k<=r)ret=min(ret,li[j].v[k]); } } at+=li[j].v.size(); } printf("%d\n",ret); } if(p==2){ int at=0; for(int j=0;j<li.size();j++){ if(q<at+li[j].v.size()){ li[j].v[q-at]=r; li[j].m=99999999; for(int k=0;k<li[j].v.size();k++)li[j].m=min(li[j].m,li[j].v[k]); break; } at+=li[j].v.size(); } } if(i%SQ==SQ-1){ int at=0; for(int j=0;j<li.size();j++) for(int k=0;k<li[j].v.size();k++) tmp[at++]=li[j].v[k]; now=wolf(); li.clear(); for(int j=0;j<a;j++){ now.v.push_back(tmp[j]); now.m=min(now.m,tmp[j]); if(j%SQ==SQ-1){li.push_back(now);now=wolf();} } if(now.v.size())li.push_back(now); } } }