• HDU 1754 I Hate It (数组实现线段树)


    很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。 
    这让很多学生很反感。 

    不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。

    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
            

    代码:

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <cstdio>
    
    using namespace std;
    
    typedef long long ll;
    
    int board[600005];//一般大小至少为三倍
    int data[200005][2];//分别记录每个点的数值和在board中的下标 
    
    void Build(int head,int left,int right){//建树 
    	if(left == right){
    		board[head] = data[left][0];
    		data[left][1] = head;
    		return;
    	}
    	int mid = left+(right-left)/2;
    	Build(head<<1,left,mid);
    	Build(head<<1|1,mid+1,right);
    	board[head] = max(board[head<<1],board[head<<1|1]);
    } 
    
    void Updata(int Num){//自下往上更新 
    	board[Num] = max(board[Num<<1],board[Num<<1|1]);
    	if(Num>1 && Num&1){
    		Updata((Num-1)/2);
    	}
    	else if(Num>1 && Num%2==0){
    		Updata(Num/2);
    	}
    }
    
    int Find(int head,int left,int right,int FL,int FR){//单点查询 
    	if(FL<=left && FR>=right)return board[head];
    	else if(FL>right || FR<left)return -1;//查询区间与当前区间不想交返回一个不相关的值。 
    	int mid = left + (right-left)/2;
    	return max(Find(head<<1,left,mid,FL,FR),Find(head<<1|1,mid+1,right,FL,FR));
    }
    
    int main(){
    	int N,M;
    	while(cin>>N>>M){
    		for(int i=1 ; i<=N ; i++){
    			scanf("%d",&data[i][0]);
    		}	
    		Build(1,1,N);
    		char ch;
    		int A,B;
    		while(M--){
    			getchar();
    			scanf("%c %d %d",&ch,&A,&B);
    			if(ch == 'U'){
    				board[data[A][1]] = B; 
    				data[A][0] = B;
    				if(data[A][1]&1)Updata((data[A][1]-1)/2);
    				else Updata(data[A][1]/2);
    			}else if(ch == 'Q'){
    				printf("%d
    ",Find(1,1,N,A,B));
    			}
    		}
    	}
    	
    	return 0;
    }
    

  • 相关阅读:
    StringBuffer和StringBuilder
    String类
    软件设计师考点总结(一)
    基于 Axis2的webService接口的基本开发步骤
    Linux学习Day10:LVM(逻辑卷管理器)
    Linux学习Day9:使用RAID(独立冗余磁盘阵列)
    Linux学习Day8:挂载硬盘设备、添加交换分区
    Linux学习Day7:用户身份与文件权限、su命令与sudo服务
    Linux学习Day6:编写Shell脚本、配置计划任务
    Linux学习Day5:Vim编辑器、配置网卡、配置Yum软件本地仓库
  • 原文地址:https://www.cnblogs.com/vocaloid01/p/9514152.html
Copyright © 2020-2023  润新知