zoukankan      html  css  js  c++  java
  • hdu1754 I hate it

    /*
    I Hate It
    
    Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 25528    Accepted Submission(s): 10099
    
    
    Problem Description
    很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
    这让很多学生很反感。
    
    不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
    
    
    Input
    本题目包含多组测试,请处理到文件结束。
    在每个测试的第一行,有两个正整数 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。
    
    
    Output
    对于每一次询问操作,在一行里面输出最高成绩。
    
    
    Sample Input
    5 6
    1 2 3 4 5
    Q 1 5
    U 3 6
    Q 3 4
    Q 4 5
    U 2 9
    Q 1 5
    
    
    Sample Output
    5
    6
    5
    9
    
    Hint
    Huge input,the C function scanf() will work better than cin
    
    
    
    Author
    linle
    
    
    Source
    2007省赛集训队练习赛(6)_linle专场
    
    */
    #include <iostream>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<string.h>
    #include<stdio.h>
    #include<stdlib.h>
    using namespace std;
    #define maxn 200010
    struct data
    {
        int l,r,max;
    }node[3*maxn];
    int score[maxn];
    void btree(int left,int right,int u)
    {
        node[u].l=left;
        node[u].r=right;
        if(left==right)
        {
          node[u].max=score[left];
        }
        else
        {
            btree(left,(left+right)>>1,2*u);
            btree(((left+right)>>1)+1,right,2*u+1);
            node[u].max=max(node[2*u].max,node[2*u+1].max);
        }
    }
    void update(int str,int val,int u)
    {
        node[u].max=max(val,node[u].max);
        if(node[u].l==node[u].r)
        {
            return;
        }
        if(str<=node[2*u].r)
        {
            update(str,val,2*u);
        }
        else
        {
            update(str,val,2*u+1);
        }
    }
    int query(int left,int right,int u)
    {
        if(node[u].l==left&&node[u].r==right)
        {
            return node[u].max;
        }
        if(right<=node[2*u].r)
        {
            return query(left,right,2*u);
        }
        if(left>=node[2*u+1].l)
        {
            return query(left,right,2*u+1);
        }
        int mid=(node[u].l+node[u].r)>>1;
        return max(query(left,mid,2*u),query(mid+1,right,2*u+1));
    }
    int main()
    {
        int N,M;
        while(scanf("%d%d",&N,&M)!=EOF)
        {
            int i;
            for(i=1;i<=N;i++)
            {
                scanf("%d",&score[i]);
            }
            getchar();
            char c;
            int s,e;
            btree(1,N,1);
            for(i=0;i<M;i++)
            {
                scanf("%c%d%d",&c,&s,&e);
                getchar();
                if(c=='U')
                update(s,e,1);
                if(c=='Q')
                {
                    printf("%d
    ",query(s,e,1));
                }
            }
        }
        return 0;
    }
    /*
    Author  style:
    在代码前先介绍一些我的线段树风格:
    maxn是题目给的最大区间,而节点数要开4倍,确切的来说节点数要开大于maxn的最小2x的两倍
    lson和rson分辨表示结点的左儿子和右儿子,由于每次传参数的时候都固定是这几个变量,所以可以用预定于比较方便的表示
    以前的写法是另外开两个个数组记录每个结点所表示的区间,其实这个区间不必保存,一边算一边传下去就行,只需要写函数的时候多两个参数,结合lson和rson的预定义可以很方便
    PushUP(int rt)是把当前结点的信息更新到父结点
    PushDown(int rt)是把当前结点的信息更新给儿子结点
    rt表示当前子树的根(root),也就是当前所在的结点
    大神的最简洁的方法
    ---继敌兵布阵---就简单的改了一点点,霸气
    NotOnlySuccess
    http://www.notonlysuccess.com/index.php/segment-tree-complete/
    */
    #include <iostream>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<string.h>
    #include<stdio.h>
    #include<stdlib.h>
    using namespace std;
    //#define maxn 50100
    const int maxn = 222222;
    #define lson l, m , rt<<1
    #define rson m+1 , r ,rt<<1|1
    int  MAX[maxn<<2];
    void PushUP(int rt)
    {
        MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
    }
    void cre(int l,int r,int rt)
    {
        if(l==r)
        {
            scanf("%d",&MAX[rt]);
            return ;
        }
        int m = (l+r)>>1;
        cre(lson);
        cre(rson);
        PushUP(rt);
    }
    void update(int p,int sc, int l,int r,int rt)
    {
        if(l==r)
        {
            MAX[rt]=sc;
            return ;
        }
        int m = (l + r)>>1;
        if(p<=m) update(p,sc,lson);
        else update(p,sc,rson);
        PushUP(rt);
        // 和方法2对照发现两个递归有点区别,法2是先把根节点的和更新,而
        //法3是先更新叶子节点,然后反过来更新根节点
    }
    int qur(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)
        {
            return MAX[rt];
        }
        //大神是分数组的区间,而我们是分要求的区间,所以他是小于等于,真妙   
    int m = (l + r)>>1; int ret = 0; if(L<=m) ret=max(ret,qur(L,R,lson)); if(R>m) ret=max(ret,qur(L,R,rson)); return ret; } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { cre(1,n,1); while(m--) { char ch[2]; int a,b; scanf("%s%d%d",ch,&a,&b); if(ch[0]=='Q') printf("%d ",qur(a,b,1,n,1)); else update(a,b,1,n,1); } } return 0; }
  • 相关阅读:
    hdu 4027 Can you answer these queries?
    hdu 4041 Eliminate Witches!
    hdu 4036 Rolling Hongshu
    pku 2828 Buy Tickets
    hdu 4016 Magic Bitwise And Operation
    pku2886 Who Gets the Most Candies?(线段树+反素数打表)
    hdu 4039 The Social Network
    hdu 4023 Game
    苹果官方指南:Cocoa框架(2)(非原创)
    cocos2d 中 CCNode and CCAction
  • 原文地址:https://www.cnblogs.com/heqinghui/p/3192587.html
Copyright © 2011-2022 走看看