首页 > 代码库 > 线段树——忠诚——洛谷——1816

线段树——忠诚——洛谷——1816

本次的目的主要在于练一练线段树的模板。

这题做法颇多,可以RMQ也可以线段树

技术分享
#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;
}
View Code

在做这题的过程中,我发现线段树,如果单点更新没有

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同意,禁止转载,侵权者必究。

线段树——忠诚——洛谷——1816