本次的目的主要在于练一练线段树的模板。
这题做法颇多,可以RMQ也可以线段树
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<iostream> #include<cstdio> using namespace std; inline int read(){ int t=1,num=0;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();} return num*t; } const int maxn=100010,INF=0x7fffffff; inline int min(int a,int b){return a<b?a:b;} int a[maxn],t[4*maxn],n,m; void build(int ro,int l,int r){ if(l==r){t[ro]=a[l];return;} int mid=(l+r)>>1; build(ro*2,l,mid);build(ro*2+1,mid+1,r); t[ro]=min(t[ro*2],t[ro*2+1]); } int ask(int ro,int l,int r,int x,int y){ if(x>r||y<l)return INF; if(x<=l&&r<=y)return t[ro]; int mid=(l+r)>>1; return min(ask(ro*2,l,mid,x,y),ask(ro*2+1,mid+1,r,x,y)); } int main() { n=read();m=read(); for(int i=1;i<=n;i++)a[i]=read(); build(1,1,n); for(int i=1;i<=m;i++){ int x=read(),y=read(); printf("%d ",ask(1,1,n,x,y)); } return 0; }
在做这题的过程中,我发现线段树,如果单点更新没有
if(x<=mid)change(ro*2,l,mid); else change(ro*2+1,mid+1,r);
或者
if(x<l||x>r) return;
的话,时间效率会退化成o(n)。
然后我没加,这就成了我这题T了的原因。
不要问我会写到单点修改。其实上述代码中并没有单点修改。
本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。