1. 程式人生 > >洛谷 P1531 I Hate It

洛谷 P1531 I Hate It

需要 namespace 字符 ref str 現在 .org build blog

P1531 I Hate It

題目背景

很多學校流行一種比較的習慣。老師們很喜歡詢問,從某某到某某當中,分數最高的是多少。這讓很多學生很反感。

題目描述

不管你喜不喜歡,現在需要你做的是,就是按照老師的要求,寫一個程序,模擬老師的詢問。當然,老師有時候需要更新某位同學的成績

輸入輸出格式

輸入格式:

第一行,有兩個正整數 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‘的時候,表示這是一條更新操作,如果當前A學生的成績低於B,則把ID為A的學生的成績更改為B,否則不改動。

輸出格式:

對於每一次詢問操作,在一行裏面輸出最高成績

輸入輸出樣例

輸入樣例#1: 復制

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

輸出樣例#1: 復制
5
6
5
9

思路:線段樹板子題
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define N 200001
using namespace std;
int n, m, x, y;
char s;
struct nond {
    
int ll, rr; int sum; }tree[4*N]; void up(int now) { tree[now].sum = max(tree[now*2].sum, tree[now*2+1].sum); } void build(int now, int l, int r) { tree[now].ll = l; tree[now].rr = r; if(tree[now].ll == tree[now].rr) { scanf("%d", &tree[now].sum); return ; }
int mid = (l+r) / 2; build(now*2, l, mid); build(now*2+1, mid+1, r); up(now); } void change(int now, int x, int y){ if(tree[now].ll == tree[now].rr) { tree[now].sum = max(y, tree[now].sum); return ; } int mid = (tree[now].ll+tree[now].rr) / 2; if(x <= mid) change(now*2, x, y); else change(now*2+1, x, y); up(now); } int query(int now, int l, int r) { if(tree[now].ll==l && tree[now].rr==r) { return tree[now].sum; } int mid = (tree[now].ll+tree[now].rr) / 2; if(l<=mid && mid<r) return max(query(now*2, l, mid), query(now*2+1, mid+1,r)); else if(r<=mid) return query(now*2, l, r); else return query(now*2+1, l, r); } int main() { scanf("%d%d", &n, &m); build(1, 1, n); for(int i = 1; i <= m; i++) { cin>>s>>x>>y; if(s == U) change(1, x, y); else printf("%d\n", query(1, x, y)); } return 0; }

 

洛谷 P1531 I Hate It