HDU1754

来源:互联网 发布:林弯弯网店淘宝网址 编辑:程序博客网 时间:2024/06/03 18:23

线段树

#include<stdio.h>#include<string.h>#define MAXN 200005struct ST //存储类型{    int l,r,max; //max表示当前节点的最大值}st[4*MAXN];inline int max(int a,int b){return a>b?a:b;}void build(int ll,int rr,int n) //初始化建立线段树{    st[n].l=ll;   //表示当前节点的最左端,    st[n].r=rr;   //表示当前节点的最右端,    st[n].max=0;  //当前节点的值,初始化全为零,    if (ll==rr) return ; //如果遇到了根节点    int mid=(ll+rr)/2;   //将当前节点分开,mid为左孩子的右端点,为右孩子的左端点;    build(ll,mid,2*n);  //先遍历左边的树    build(mid+1,rr,2*n+1); //再遍历右边的树}void insert(int ll,int rr,int a,int n)  // 更新{    if (st[n].l==ll&&st[n].r==rr)        {st[n].max=a;return ;}//如果找到,就赋值,退出。    else if (a>st[n].max)        st[n].max=a; //从新更新;    int mid=(st[n].l+st[n].r)/2;    if (rr<=mid) //如果右端点比他的中间区分值mid还小,那么久插到左边,        insert(ll,rr,a,2*n);else if (ll>=mid+1)   //如果左端点比他的中间区分值mid还大,那么久插到右边,     insert(ll,rr,a,2*n+1);}int find(int ll,int rr,int n)   // 查询{    if (st[n].l==ll&&st[n].r==rr)        return st[n].max;     //返回max;    int mid=(st[n].l+st[n].r)/2;    if (rr<=mid)         //如果rr小于中点分解值,那么就查找左孩子,     find(ll,rr,2*n);else if (ll>=mid+1) //如果rr大于于中点分解值,那么就查找右孩子,        find(ll,rr,2*n+1);    else    return max(find(ll,mid,2*n),find(mid+1,rr,2*n+1));}int main(){    int n,m,a,b,i;    char op;    while (scanf("%d%d",&n,&m)!=EOF)    {        build(1,n,1);        for (i=1;i<=n;++i)        {            scanf("%d",&a);            insert(i,i,a,1);        }        getchar();        for (i=1;i<=m;++i)        {            scanf("%c %d %d",&op,&a,&b);getchar();            if (op=='Q') printf("%d\n",find(a,b,1));            if (op=='U') insert(a,a,b,1);        }    }    return 0;}



0 0
原创粉丝点击