HDU 1754 I Hate It (array implements segment tree)

A habit of comparison is popular in many schools. Teachers like to ask what is the highest score from so-and-so to so-and-so. 
This disgusts many students. 

Whether you like it or not, what you need to do now is to write a program according to the teacher's request to simulate the teacher's inquiry. Of course, teachers sometimes need to update a student's grades.

Input

This question contains multiple sets of tests, please process until the end of the file. 

In the first line of each test, there are two positive integers N and M ( 0<N<=200000, 0<M<5000 ), which represent the number of students and the number of operations, respectively. 

Student ID numbers are numbered from 1 to N, respectively. 
The second line contains N integers representing the initial grades of the N students, where the ith number represents the grades of the student whose ID is i. 
Next there are M lines. Each line has a character C (only take 'Q' or 'U'), and two positive integers A, B. 
When C is 'Q', it means that this is a query operation, which asks the students whose IDs range from A to B (including A and B), which is the highest grade. 

When C is 'U', it means that this is an update operation, which requires changing the grade of the student whose ID is A to B.

 

Output

For each query operation, output the highest score in one line.

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
        

Code:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cstdio>

using namespace std;

typedef long long ll;

int board[600005];//The general size is at least three times
int data[200005][2];//Record the value of each point and the subscript in the board respectively

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)/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){//Update from bottom to top
	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){//Single point query
	if(FL<=left && FR>=right)return board[head];
	else if(FL>right || FR<left)return -1;//The query interval and the current interval do not want to return an irrelevant value.
	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\n",Find(1,1,N,A,B));
			}
		}
	}
	
	return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325949294&siteId=291194637