zoukankan      html  css  js  c++  java
  • HDU 1754 区间查询,单点更新

    I Hate It

    Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 79439    Accepted Submission(s): 30513


    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
     
    已经在Hint说了cin可能会超时,但是发现了一个黑科技:ios::sync_with_stdio(false); 原理:http://blog.csdn.net/yujuan_mao/article/details/8119529
     
    然后就是这道题:
    第一次建树后模型:

    father数组存叶子编号,方便单点向上更新区间最大值。

    这里的结构体里面value就是区间最大值,在其他题中也可以是区间和或者其他。

     测试样例第一次更新后node节点如下:

    当第三个人分数更新为6时,从区间[3,3]开始向上更新,包含3的区间都会被更新。

    编号类似二叉树层次遍历

    #include <bits/stdc++.h>
    
    using namespace std;
    const int MAXNODE = 1<<19;
    const int MAX = 2e6+10;
    struct NODE {
        int value;
        int left,right;
        }node[MAXNODE];
    
    int father[MAX];//叶子节点的编号
    
    void BuildTree(int i,int left,int right) {
        node[i].left = left;
        node[i].right = right;
        node[i].value = 0;
        if(left == right) {
            father[left] = i;
            return ;
        }
        BuildTree(i<<1,left,(int)(floor(left+right)/2.0));
        BuildTree((i<<1)+1,(int)(floor(left+right)/2.0+1),right);//注意这里的优先级
    }
    
    //向上更新
    void UpdateTree(int ri) {
        if(ri ==1 ) return;
        int fi = ri/2;
        int a = node[fi<<1].value;
        int b = node[(fi<<1)+1].value;
        node[fi].value = max(a,b);
        UpdateTree(ri/2);
    }
    
    int Max;
    void Query(int i,int l,int r) {
        if(node[i].left == l&&node[i].right == r) {
            Max = max(Max,node[i].value);
            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++;
        if(r >= node[i].left) {
            if(l >= node[i].left) Query(i,l,r);
            else Query(i,node[i].left,r);
        }
    }
    
    int main()
    {
        freopen("in.txt","r",stdin);
        int n,m,g;
        ios::sync_with_stdio(false);
        while(cin>>n>>m) {
            BuildTree(1,1,n);
            for(int i = 1; i <= n; i++) {
                cin>>g;
                node[father[i]].value = g;
                UpdateTree(father[i]);
            }
            string op;
            int a,b;
            while(m--) {
                cin>>op>>a>>b;
                if(op[0] == 'Q') {
                    Max = 0;
                    Query(1,a,b);
                    cout<<Max<<endl;
                }
                else {
                    node[father[a]].value = b;
               UpdateTree(father[a]); } } }
    return 0; }
  • 相关阅读:
    Android笔记之调用系统相机拍照
    Android笔记之RoundedImageView
    Java笔记之public、protected、default和private
    Android笔记之ExpandableListView(悬浮吸顶Demo)
    Android笔记之Fragment中创建ViewModel的正确方式
    Android代号、版本及API级别之间的对应关系
    【Phabricator】教科书一般的Phabricator安装教程(配合官方文档并带有踩坑解决方案)
    【Ansible】记一次技术博客害死人的经历——ansible模板变量注入探究
    【linux杂谈】遇到REMOTE HOST IDENTIFICATION HAS CHANGED怎么办?
    【linux杂谈】在SSH连接中,openssh如何解决'Connection refused'错误?
  • 原文地址:https://www.cnblogs.com/zhangmingzhao/p/7256563.html
Copyright © 2011-2022 走看看