zoukankan      html  css  js  c++  java
  • I Hate It

    I Hate It
    Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

    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 

    在一个指定区间里找最大值,并且值还会时不时更新,由于数据太多,所以暴力搜索肯定TLE,那么线段树来了,
    每一个树上有它所覆盖的数的最左边和最右边的下标,还有在这个区间里的最大值。
    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    #define N 200000
    #define INF 0xfffffff
    
    int MAX, a[N];
    
    struct node
    {
        int l, r, Max;
        int mid()
        {
            return (l+r)/2;
        }
    }tree[4*N];
    
    void Build(int root, int l, int r)  // 建树
    {
        tree[root].l = l, tree[root].r = r;
    
        if(tree[root].l == tree[root].r)
        {
            tree[root].Max = a[l];  // 如果是叶子节点最大值就是它自身
            return;
        }
        Build(root*2, l, (l+r)/2);
        Build(root*2+1, (l+r)/2+1, r);
    
        tree[root].Max = max(tree[root*2].Max, tree[root*2+1].Max);   // 这棵树上最大值等于它左儿子树上的最大值和它右儿子最大值的最大值
    }
    
    void query(int root, int l, int r) // 查询,l~r区间最大值
    {
        if(tree[root].l == l && tree[root].r == r)
        {
            MAX = max(tree[root].Max, MAX);  // 总区间最大值等于 原本所得最大值和部分区间最大值的最大值
            return ;
        }
    
        if(r <= tree[root].mid())   // 继续查询
            query(root*2, l, r);
        else if(l > tree[root].mid())
            query(root*2+1, l, r);
        else
        {
            query(root*2, l, tree[root].mid());
            query(root*2+1, tree[root].mid()+1, r);
        }
    }
    
    void update(int root, int q, int b)  // 更新到叶子节点
    {
        if(tree[root].l == q && tree[root].r == q)  // if 到了叶子节点,那么它的值被改变,最大值也被改变,就是被改变后的值
        {
            a[q] = b;
            tree[root].Max = a[q];
            return ;
        }
        if(q <= tree[root].mid())
            update(2*root, q, b);
        else
            update(2*root+1, q, b);
        tree[root].Max = max(tree[root*2].Max, tree[root*2+1].Max);  // 树上最大值等于左儿子和右儿子最大值的最大值
    }
    
    int main()
    {
        int n, q, l, r;
        char s[3];
    
        while(scanf("%d%d", &n, &q) != EOF)
        {
            for(int i = 1; i <= n; i++)
                scanf("%d", &a[i]);
    
            Build(1, 1, n);
    
            for(int i = 0; i < q; i++)
            {
                scanf("%s%d%d", s, &l, &r);
    
                if(s[0] == 'Q')
                {
                    MAX = -INF;  // 最开始把MAX初始化
                    query(1, l, r);
                    printf("%d
    ", MAX);
                }
                else
                    update(1, l, r);  //更新
            }
        }
        return 0;
    }
    让未来到来 让过去过去
  • 相关阅读:
    一个禁止某个document element对象选中文本的js方法
    LNMP中nginx和php的安装流程
    nginx编译
    nginx服务器管理
    nginx+phpfpm配置文件的组织结构
    win 8 x64 english key
    WdatePicker 设置时间范围在某个时间段
    Vm workstation安装win8 的问题
    android 开发中xml的解析
    多线程下载文件
  • 原文地址:https://www.cnblogs.com/Tinamei/p/4699742.html
Copyright © 2011-2022 走看看