线段树各种小练习
1.对于一个整数数组,要求资持单点修改,查询区间l r中的max(ai-aj)(l<=j<i<=r)
/* 对于每个合并 答案=左孩子的ans 右孩子的ans 右孩子的max-左孩子的min 三者取大 */ #include<iostream> #include<cstdio> #include<cstring> #define maxn 100010 #define inf 0x3f3f3f3f using namespace std; int n,m,a[maxn],num; struct node { int l,r,lc,rc; int Max,Min,ans; }t[maxn*4]; int init() { int x=0;char s=getchar();while(s<'0'||s>'9')s=getchar(); while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}return x; } void Build(int li,int ri) { int k=++num; t[k].l=li,t[k].r=ri; if(li!=ri-1) { t[k].lc=num+1;Build(li,(li+ri)/2); t[k].rc=num+1;Build((li+ri)/2,ri); t[k].Max=max(t[t[k].lc].Max,t[t[k].rc].Max); t[k].Min=min(t[t[k].lc].Min,t[t[k].rc].Min); t[k].ans=max(t[t[k].rc].Max-t[t[k].lc].Min,max(t[t[k].lc].ans,t[t[k].rc].ans)); } else {t[k].ans=-inf;t[k].Max=a[li];t[k].Min=a[li];} } void Change(int k,int li,int ri,int data) { if(li<=t[k].l&&ri>=t[k].r) { t[k].Max=data;t[k].Min=data; t[k].ans=-inf;return; } int mid=(t[k].l+t[k].r)/2; if(li<mid)Change(t[k].lc,li,ri,data); if(ri>mid)Change(t[k].rc,li,ri,data); t[k].Max=max(t[t[k].lc].Max,t[t[k].rc].Max); t[k].Min=min(t[t[k].lc].Min,t[t[k].rc].Min); t[k].ans=max(t[t[k].rc].Max-t[t[k].lc].Min,max(t[t[k].lc].ans,t[t[k].rc].ans)); } int Query_max(int k,int li,int ri) { if(li<=t[k].l&&ri>=t[k].r)return t[k].Max; int ret=-inf,mid=(t[k].l+t[k].r)/2; if(li<mid)ret=max(ret,Query_max(t[k].lc,li,ri)); if(ri>mid)ret=max(ret,Query_max(t[k].rc,li,ri)); return ret; } int Query_min(int k,int li,int ri) { if(li<=t[k].l&&ri>=t[k].r)return t[k].Min; int ret=inf,mid=(t[k].l+t[k].r)/2; if(li<mid)ret=min(ret,Query_min(t[k].lc,li,ri)); if(ri>mid)ret=min(ret,Query_min(t[k].rc,li,ri)); return ret; } int Query(int k,int li,int ri) { if(li<=t[k].l&&ri>=t[k].r)return t[k].ans; int ret=-inf,mid=(t[k].l+t[k].r)/2; if(li<mid)ret=max(ret,Query(t[k].lc,li,ri)); if(ri>mid)ret=max(ret,Query(t[k].rc,li,ri)); if(li<mid&&ri>mid)ret=max(ret,Query_max(t[k].rc,mid,ri)-Query_min(t[k].lc,li,mid)); return ret; } int main() { n=init();m=init(); for(int i=1;i<=n;i++) a[i]=init(); Build(1,n+1);int x,y,z; for(int i=1;i<=m;i++) { x=init();y=init();z=init(); if(x==1)Change(1,y,y+1,z); if(x==2)printf("%d\n",Query(1,y,z+1)); } return 0; }