线段树回顾<找区间最小值,点修改>

来源:互联网 发布:淘宝外国儿童模特 编辑:程序博客网 时间:2024/05/23 21:51

注意查找的时候,因为进的区间必定包含有。

那么只要l>这个区间的mid,就要右边

r<=这个区间的min,就要左边,

l在mid左边,r在mid右边就2边都要。

当l r 包含这个区间的时候,就取最小值然后return

#include<iostream>#include <stdio.h>#include <string.h>#include <math.h>using namespace std;struct ttt{int left,right,min;};ttt qq[50000];void init(int l,int r,int x){qq[x].left=l;qq[x].right=r;qq[x].min=1e9+7;if(l==r)return ;init(l,(l+r)/2,x+x);init((l+r)/2+1,r,x+x+1);}int update(int x,int y,int num){int left1=qq[num].left;int right1=qq[num].right;int mid1=(left1+right1)/2;if(qq[num].left==qq[num].right&&qq[num].left==x){if(qq[num].min==1e9+7)qq[num].min=y;elseqq[num].min+=y;return 0;}if(x<=mid1){update(x,y,num+num);}else{update(x,y,num+num+1);}qq[num].min=min(qq[num+num].min,qq[num+num+1].min);}int minn;int find1(int l,int r,int num){ //在l,r包括的全部中找 //cout << qq[num].left <<"   " << qq[num].right  << endl;if(l<=qq[num].left&&r>=qq[num].right){//cout << "进来了" << endl;minn=min(minn,qq[num].min);return 0;}if(l>(qq[num].left+qq[num].right)/2){find1(l,r,num+num+1);}if(r<=(qq[num].left+qq[num].right)/2){find1(l,r,num+num);}if(r>(qq[num].left+qq[num].right)/2&&l<=(qq[num].left+qq[num].right)/2){find1(l,r,num+num);find1(l,r,num+num+1);}}int main(){//freopen("in.txt","r",stdin);int i,k,j,f1,f2,f3,f4,t1,t2,t3,t4,l1,l2,n,m;init(1,200,1);minn=1e9+7;update(5,513,1);update(4,88,1);update(3,8,1);update(2,7,1);find1(2,5,1);cout << minn << endl;return 0;}