hdu 1754 I Hate It

来源:互联网 发布:python 中英文对照 编辑:程序博客网 时间:2024/06/05 22:50
题意:有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目。 
学生ID编号分别从1编到N。 
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩。 
接下来有M行。每一行有一个字符 C (只取'Q'或'U') ,和两个正整数A,B。 
当C为'Q'的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。 

当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。

对于每一次询问操作,在一行里面输出最高成绩。


这题是一道最基础的线段树模板题,没什么难度,就是单点更新和求区间最大值。

我参照了两个模板,一个用了结构体


代码1:

#include <cstdio>#include <cstring>#include <iostream>using namespace std;int n,m;int maxn[200000 << 2];void build(int rt, int l, int r){    if(l == r)    {        scanf("%d",&maxn[rt]);        return;    }    int mid = (l + r) >> 1;    build(rt << 1, l, mid);    build(rt << 1|1, mid + 1, r);    maxn[rt] = max(maxn[rt << 1],maxn[rt << 1|1]);}void update(int x, int z, int l, int r, int rt){    if(l == r) // 更新到叶子节点    {        maxn[rt] = z;        return;    }    int mid = (l + r) >> 1;    if(x <= mid)        update(x, z, l, mid, rt << 1);    else update(x, z, mid + 1, r, rt << 1|1);    maxn[rt] = max(maxn[rt << 1],maxn[rt << 1|1]);}int query(int L, int R, int l, int r, int rt){    if(L <=l && r <=R)    {        return(maxn[rt]);    }    int mid = (l + r) >> 1;    int Max = 0;    if(L <= mid)   //这里拆分区间        Max = max(Max,query(L, R, l, mid ,rt << 1));    if(R > mid)  //区间的左右两部分都要加进去,所以此处没有else语句        Max = max(Max,query(L, R, mid + 1, r, rt << 1|1));    return(Max);}int main(){    while(~scanf("%d %d",&n, &m))    {        build(1,1,n);        for(int j=1;j<=m;j++)        {            getchar();            char c;            int a,b;            scanf("%c %d %d",&c, &a, &b);            if(c == 'Q')            {                printf("%d\n",query(a,b,1,n,1));            }            else if(c == 'U')            {                update(a,b,1,n,1);            }        }    }    return 0;}


#include <cstdio>#include <cstring>#include <iostream>using namespace std;struct aa{    int v;    int left,right;}node[524288];int father[200001];//每个点(当区间长度为0时,对应一个点)对应的结构体数组下标int Max;int n,m;void BuildTree(int i, int left, int right){    node[i].left = left;    node[i].right = right;    node[i].v = 0;    if(left == right)    {        father[left]=i;        return;    }    BuildTree(i << 1 , left , (left + right)/2);    BuildTree((i << 1)+1 , (left + right)/2 + 1, right);}void UpdateTree(int ri)//该点本身在函数外已更新过{    if(ri ==  1)return;    int fi = ri / 2;  //父节点,从下往上更新    int a = node[fi << 1].v;    int b = node[(fi << 1) + 1].v;    node[fi].v = max(a,b);    UpdateTree(ri/2);}void Query(int i, int l ,int r){    if(node[i].left == l && node[i].right == r)    {        Max=max(Max,node[i].v);        return;    }    i= i << 1;    if(l <= node[i].right )    {        if(r <= node[i].right)            Query(i, l, r);        else            Query(i, l ,node[i].right);    }    i +=1; // 右子树    if(r >= node[i].left)    {        if(l >= node[i].left)            Query(i, l, r);        else            Query(i, node[i].left, r);    }}int main(){    while(scanf("%d %d",&n,&m)!=EOF)    {        BuildTree(1, 1, n);        for(int i=1;i<=20;i++)            printf("%d ",node[i].v);        printf("\n");        for(int i=1;i<=n;i++)        {            int a;            scanf("%d",&a);            node[father[i]].v = a;            UpdateTree(father[i]);            for(int i=1;i<=20;i++)            printf("%d ",node[i].v);        printf("\n");        }        for(int i=1;i<=m;i++)        {            int A,B;            char c;            getchar();            scanf("%c %d %d",&c,&A,&B);            //printf("%c\n",c);            if(c == 'Q')            {                Max=-1000000;                Query(1, A, B);                printf("%d\n",Max);            }            else if(c == 'U')            {                node[father[A]].v = B;                UpdateTree(father[A]);            }        }    }    return 0;}

 

0 0
原创粉丝点击