zoukankan      html  css  js  c++  java
  • hdoj1754-I Hate It && 1166-敌兵布阵

    题目链接

    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

    思路

          此题属于线段树求区间最大值的模板题,详解见大神MetalSeed博客;

    code

    #include <iostream>
    #include <fstream>
    using namespace std;
    
    const int MAX = 200000+5;
    
    class Node      //节点
    {
            public:
                    int l, r, v; //区间的左右边界及区间内的最大值V
    };
    
    Node node[4*MAX];
    int grade[MAX];
    int n, m;
    
    void creat(int root, int l, int r)
    {
            node[root].l = l;
            node[root].r = r;
            if(l == r)
            {
                    node[root].v = grade[l];
                    return ;
            }
            int m = l + (r - l) / 2;
            creat(root * 2, l, m);
            creat(root * 2 + 1, m + 1, r);
            node[root].v = node[root*2].v > node[root*2+1].v? node[root*2].v : node[root*2+1].v;
    }
    
    void update(int root, int x, int _v)
    {
            if(node[root].l == node[root].r)
            {
                    node[root].v = _v;
                    return ;
            }
            if(x <= node[root*2].r)
            {
                    update(root*2, x, _v);
            }
            else
            {
                    update(root*2+1, x, _v);
            }
            node[root].v = node[root*2].v > node[root*2+1].v? node[root*2].v : node[root*2+1].v;
    }
    
    int query(int root, int l, int r)
    {
            if(node[root].l == l && node[root].r == r)
            {
                    return node[root].v;
            }
            int s;
            if(r <= node[root*2].r)
            {
                    s = query(root*2, l, r);
            }
            else if(l >= node[root*2+1].l)
            {
                    s = query(root*2+1, l, r);
            }
            else
            {
                    int s1 = query(root*2, l, node[root*2].r);
                    int s2 = query(root*2+1, node[root*2+1].l, r);
                    s = s1 > s2? s1 : s2;
            }
            return s;
    }
    
    int main()
    {
            //ifstream cin("data.in");
            std::ios::sync_with_stdio(false);
            std::cin.tie(0);
            while(cin >> n >> m)
            {
                    for(int i = 1; i <= n; ++ i)
                    {
                            cin >> grade[i];
                    }
                    creat(1, 1, n);
                    for(int i = 0; i < m; ++ i)
                    {
                            char ch;
                            cin >> ch;
                            if(ch == 'U')
                            {
                                    int x, v;
                                    cin >> x >> v;
                                    update(1, x, v);
                            }
                            else
                            {
                                    int l, r;
                                    cin >> l >> r;
                                    cout << query(1, l, r) << endl;
                            }
                    }
            }
        return 0;
    }
    

    hdoj1166-敌兵布阵

          此题属于球区间的数值和问题;

    code:

    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <fstream>
    #include <cstdio>
    
    using namespace std;
    
    class Node
    {
            public:
                    int l, r, v;
    };
    const int MAX = 50000+5;
    
    Node segTree[4*MAX];
    int data[MAX];
    
    void creat(int root, int l, int r)
    {
            segTree[root].l = l;
            segTree[root].r = r;
            if(l == r)
            {
                    segTree[root].v = data[l];
    
            }
            else
            {
                    int mid = (l + r) >> 1;
                    creat(2*root, l, mid);
                    creat(2*root+1, mid+1, r);
                    segTree[root].v = segTree[2*root].v + segTree[2*root+1].v;
            }
    }
    
    void update(int root, int x, int _v)
    {
            //cout << _v << endl;
            int l = segTree[root].l;
            int r = segTree[root].r;
            if(l == r)
            {
                    segTree[root].v += _v;
            }
            else
            {
                    int mid = (l + r) >> 1;
                    if(x <= mid)
                    {
                            update(2*root, x, _v);
                    }
                    else
                    {
                            update(2*root+1, x, _v);
                    }
                    segTree[root].v = segTree[2*root].v + segTree[2*root+1].v;
            }
    }
    
    int query(int root, int l, int r)
    {
            if(segTree[root].l >= l && segTree[root].r <= r)
            {
                    return segTree[root].v;
            }
            else
            {
                    int q1 = 0, q2 = 0;
                    //cout << segTree[2*root].r << endl;
                     if(r <= segTree[2*root].r)
                    {
                            q1 = query(2*root, l, r);
                    }
                    else if(l >= segTree[2*root+1].l)
                    {
                            q2 = query(2*root+1, l, r);
                    }
                    else
                    {
                            q1 = query(2*root, l, r);
                            q2 = query(2*root+1, l, r);
                    }
                    return q1 + q2;
            }
    }
    
    int main()
    {
            //freopen("data.in", "r", stdin);
            int t, cnt = 1;
            scanf("%d", &t);
            while(t -- )
            {
                    printf("Case %d:
    ", cnt ++);
                    int n;
                    scanf("%d", &n);
                    for(int i = 1; i <= n; ++ i)
                    {
                            scanf("%d", &data[i]);
                    }
                    creat(1, 1, n);
    
                    char ch[10];
                    while(~scanf("%s", ch) && ch[0] != 'E')
                    {
                            if(ch[0] == 'Q')
                            {
                                    int l, r;
                                    scanf("%d%d", &l, &r);
                                    printf("%d
    ", query(1, l, r));
                            }
                            else if(ch[0] == 'A')
                            {
                                    int x, v;
                                    scanf("%d%d", &x, &v);
                                    update(1, x, v);
                            }
                            else if(ch[0] == 'S')
                            {
                                    int x, v;
                                    scanf("%d%d", &x, &v);
                                    update(1, x, -v);
                            }
                    }
            }
            return 0;
    }
    
    
    
    
  • 相关阅读:
    jQuery诞生记-原理与机制
    你所不知的 CSS ::before 和 ::after 伪元素用法
    http中get与post的区别
    Http请求方法
    TCP/IP详解学习笔记(4)-ICMP协议,ping和Traceroute
    TCP/IP详解学习笔记(3)-IP协议,ARP协议,RARP协议
    TCP/IP详解学习笔记(2)-数据链路层
    TCP/IP详解学习笔记(1)-基本概念
    全面解析Java的垃圾回收机制
    深入Java虚拟机:JVM中的Stack和Heap
  • 原文地址:https://www.cnblogs.com/topk/p/6580084.html
Copyright © 2011-2022 走看看