线段树练手题,单点修改,区间查询,写个分块试试,分块下标用0-n-1比较好写
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1e6+5;
const int maxm=1e3+5;
int n,val[maxn],ans[maxm],l[maxm],r[maxm],belong[maxn],block,cnt;
void update(int q,int v){
int blto=belong[q];
int ff=0;
if(ans[blto]>v)ans[blto]=val[q]=v;
else if(ans[blto]==val[q]){
val[q]=v;ans[blto]=INT_MAX;
rep(i,l[blto],r[blto])ans[blto]=min(ans[blto],val[i]);
}
else {
val[q]=v;
if(block==1)ans[blto]=v;
}
}
int q(int ql,int qr){
int blto=belong[ql];
if(l[blto]==ql&&qr==r[blto])return ans[blto];
int res=INT_MAX;
rep(i,ql,qr)res=min(res,val[i]);
return res;
}
int query(int ql,int qr){
int b1=belong[ql],b2=belong[qr];
if(b1==b2)return q(ql,qr);
else {
int res=q(ql,r[b1]);
b1++;
while(b1<b2)res=min(res,ans[b1]),b1++;
res=min(res,q(l[b2],qr));
return res;
}
}
void init(){
block=sqrt(n);cnt=n/block;
rep(i,1,cnt)
l[i]=(i-1)*block+1,r[i]=i*block;
if(n%block){
l[cnt+1]=cnt*block+1;
r[cnt+1]=n;
cnt++;
}
rep(i,1,cnt)ans[i]=INT_MAX;
rep(i,1,n){
int p=i/block;
if(i%block!=0)p++;
belong[i]=p;
ans[p]=min(ans[p],val[i]);
}
}
int main(){
int q,o,ql,qr;
scanf("%d",&n);
rep(i,1,n)scanf("%d",val+i);
init();
scanf("%d",&q);
while(q--){
scanf("%d%d%d",&o,&ql,&qr);
if(o) update(ql,qr);
else printf("%d\n",query(ql,qr));
}
return 0;
}