杭电1574

来源:互联网 发布:微信平台微网站源码 编辑:程序博客网 时间:2024/06/09 20:52

I Hate It

这是个简单的线段树,求的是区间最大值,由于不停的改变,所以用线段树,否则的话RMQ就行了

线段树最基本的几个操作,Update(),Build_tree(),Qurry()这三操作是最基础的操作

节点存储的就是从第L到R的最大值,最大值不是做儿子就是右儿子

#include<stdio.h>#include<math.h>#define  N  5000000typedef struct{    __int64 L,R;    __int64 v;}T;T Node[N];__int64 father[N/2];__int64 n,m,ID;__int64 Qurry(__int64 i,__int64 left,__int64 right)//查询{    if(Node[i].L==left&&Node[i].R==right)    {        return Node[i].v;    }    __int64 a,b,max;    max=0;    if(left<=Node[2*i].R)    {        if(right<=Node[2*i].R)        {            a=Qurry(2*i,left,right);        }        else        {            a=Qurry(2*i,left,Node[2*i].R);        }        max=a;    }    if(right>=Node[2*i+1].L)    {        if(left>=Node[2*i+1].L)         b=Qurry(2*i+1,left,right);         else         b=Qurry(2*i+1,Node[2*i+1].L,right);         if(b>max)         max=b;    }    return max;}void Build_tree(__int64 i,__int64 left,__int64 right)//建树{    __int64 mid;    Node[i].L=left; Node[i].R=right; Node[i].v=0;    if(left==right)    {  if(i>ID)        ID=i;        father[left]=i;        return ;    }    mid=(int)floor((left+right)/2.0);    Build_tree(2*i,left,mid);    Build_tree(2*i+1,mid+1,right);}void Update(__int64 Id)//更新{    __int64 k;        k=Id/2;        Node[k].v=Node[2*k].v;        if(2*k+1<=ID&&Node[2*k+1].v>Node[k].v)        Node[k].v=Node[2*k+1].v;        Id=k;    while(Id>1)    {       k=Id/2;       if(Node[2*k].v>Node[2*k+1].v)       Node[k].v=Node[2*k].v;       else       Node[k].v=Node[2*k+1].v;       Id=k;   }}int main(){    while(scanf("%I64d%I64d",&n,&m)!=EOF)    {        __int64 k,i;        __int64 s,e;        char ch;        Build_tree(1,1,n);        //传输的分别是编号,左区间,右区间边界       /* for(i=1;i<=2*n;i++)         printf("%I64d\t%I64d\t%I64d\n",i,Node[i].L,Node[i].R);*/        for(i=1;i<=n;i++)        {            k=father[i];            scanf("%I64d",&Node[k].v);            Update(k);            //k表示升级的编号        }        while(m--)        {            getchar();            scanf("%c%I64d%I64d",&ch,&s,&e);            if(ch=='Q')            {                if(e>n)e=n;                printf("%I64d\n",Qurry(1,s,e));                //分别表示编号,左右区间            }            else             {                k=father[s];                Node[k].v=e;                Update(k);            }                    }    }}



原创粉丝点击