I Hate It
I Hate It
Time Limit : 9000/3000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 16 Accepted Submission(s) : 10
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。
View Code
View Code
View Code
在每个测试的第一行,有两个正整数 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
Author
linle
Source
2007省赛集训队练习赛(6)_linle专场
基础的线段树题目,单点更新,区间最值
#include <stdio.h> #include <stdlib.h> struct Line { int Left,Right; int Max; }; struct Line ID[600200]; int MAX_NUM; void Build(int l,int r,int n) { int Mid=(l+r)/2; ID[n].Left=l; ID[n].Right=r; if (l==r) {scanf("%d",&ID[n].Max);return;} Build(l,Mid,2*n); Build(Mid+1,r,2*n+1); ID[n].Max=(ID[2*n].Max>=ID[2*n+1].Max)?ID[2*n].Max:ID[2*n+1].Max; } void Updata(int l,int r,int n,int data,int S) { int Mid=(l+r)/2; if (l==r&&l==S) {ID[n].Max=data;return;} if(S<=Mid) Updata(l,Mid,2*n,data,S); else Updata(Mid+1,r,2*n+1,data,S); ID[n].Max=(ID[2*n].Max>=ID[2*n+1].Max)?ID[2*n].Max:ID[2*n+1].Max; } void Search(int r,int l,int Step) { int Mid; if (r==ID[Step].Left && l==ID[Step].Right) { if(ID[Step].Max>MAX_NUM) MAX_NUM=ID[Step].Max; return; } if (ID[Step].Left==ID[Step].Right) return; Mid=(ID[Step].Left+ID[Step].Right)/2; if (Mid>=l) Search(r,l,Step*2); else if (Mid<r) Search(r,l,Step*2+1); else { Search(r,Mid,Step*2); Search(Mid+1,l,Step*2+1); } } int main() { int M,N,a,b; char Change; while(scanf("%d%d",&N,&M)!=EOF) { Build(1,N,1); getchar(); while(M--) { scanf("%c%d%d",&Change,&a,&b); MAX_NUM=0; if(Change=='Q') { Search(a,b,1); printf("%d\n",MAX_NUM); } else if(Change=='U') Updata(1,N,1,b,a); getchar(); } } return 0; }
修改:2015.5.15
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 using namespace std; 6 /*Build(int r,int l,int n) [r,l]为所要初始化的区间,建立一颗二叉树,n初始值为1*/ 7 /*Updata(int n) 更新节点上的信息,返回左右孩子中关键值的和*/ 8 /*Change(int r,int l,int Step,int data) ,初始赋值Step=1,把该区间[r,l]或者点[a,a]上的关键值累加data*/ 9 /*Search(int r,int l,int Step) 搜索区间,初始赋值Step=1,[r,l]为需要拿去匹配的空间,获取该区间上关键值总和*/ 10 int SIGN; /*,起初赋值为0,用来保存关键值得总数*/ 11 typedef struct Line 12 { 13 int Left,Right; 14 int Key; 15 }LR; 16 LR ID[1008600];/*每一个节点都需要一个存储*/ 17 int Up_Key(int n)/*更新当前点,更新最大值*/ 18 { 19 return max(ID[2*n].Key,ID[2*n+1].Key);/*更新关键值(最大值)*/ 20 } 21 void Build(int L,int R,int n) /*输入时建立二叉树根*/ 22 { 23 int Mid=(L+R)/2; 24 ID[n].Left=L;ID[n].Right=R; 25 if (L==R) /*找到根节点的时候输入*/ 26 {scanf("%d",&ID[n].Key);return;} 27 Build(L,Mid,2*n); 28 Build(Mid+1,R,2*n+1); 29 ID[n].Key=Up_Key(n); 30 } 31 void UpData(int N,int Step,int data)/*单点更新,单点修改*/ 32 { 33 int Mid; 34 if(N==ID[Step].Left&&N==ID[Step].Right) 35 { 36 ID[Step].Key=data;return;/*单点修改成data*/ 37 } 38 Mid=(ID[Step].Left+ID[Step].Right)/2; 39 if (Mid>=N)UpData(N,Step*2,data); 40 else UpData(N,Step*2+1,data); 41 ID[Step].Key=Up_Key(Step); 42 } 43 void Search(int L,int R,int Step)/*匹配区间*/ 44 { 45 int Mid; 46 if(L==ID[Step].Left && R==ID[Step].Right) 47 { 48 SIGN=max(ID[Step].Key,SIGN);return;/*获取最大值*/ 49 } 50 Mid=(ID[Step].Left+ID[Step].Right)/2; 51 if (Mid>=R) Search(L,R,Step*2); 52 else if (Mid<L) Search(L,R,Step*2+1); 53 else 54 { 55 Search(L,Mid,Step*2); 56 Search(Mid+1,R,Step*2+1); 57 } 58 } 59 int main() 60 { 61 int N,M,i; 62 while(scanf("%d%d",&N,&M)!=EOF) 63 { 64 Build(1,N,1); 65 while(M--) 66 { 67 char Str; 68 int A,B; 69 scanf(" %c %d%d",&Str,&A,&B); 70 if(Str=='Q') 71 { 72 SIGN=0; 73 Search(A,B,1); 74 printf("%d\n",SIGN); 75 } 76 else 77 { 78 UpData(A,1,B); 79 } 80 } 81 } 82 return 0; 83 }
更新模板:2016.4.14
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #define MaxN 1008600 6 using namespace std; 7 struct Node{int L,R,Key;}ID[MaxN];/*每一个节点都需要一个存储*/ 8 int Up_Date(int n){return max(ID[2*n].Key,ID[2*n+1].Key);} 9 void Build(int L,int R,int n)/*输入时建立二叉树根,Build(1,N,1)*/ 10 { 11 ID[n].L=L;ID[n].R=R; 12 if (L==R){ 13 scanf("%d",&ID[n].Key);return; 14 } 15 int Mid=(L+R)/2; 16 Build(L,Mid,2*n);Build(Mid+1,R,2*n+1); 17 ID[n].Key=Up_Date(n); 18 } 19 void UpDate_P(int P,int n,int v) /*单点更新*/ 20 { 21 if(P==ID[n].L&&P==ID[n].R){ 22 ID[n].Key=v;return;/*单点加上Data*/ 23 } 24 int Mid=(ID[n].L+ID[n].R)/2; 25 if (Mid>=P)UpDate_P(P,n*2,v); 26 else UpDate_P(P,n*2+1,v); 27 ID[n].Key=Up_Date(n); 28 } 29 30 int Query(int L,int R,int n)/*匹配询问区间*/ 31 { 32 if(L==ID[n].L && R==ID[n].R){ 33 return ID[n].Key; 34 } 35 int Mid=(ID[n].L+ID[n].R)/2; 36 if (Mid>=R)return Query(L,R,n*2); 37 else if (Mid<L)return Query(L,R,n*2+1); 38 else{ 39 return max(Query(L,Mid,n*2),Query(Mid+1,R,n*2+1)); 40 } 41 } 42 int Num[100860]; 43 int main() 44 { 45 char Str; 46 int T,t=1,N,M,A,B; 47 while(scanf("%d%d",&N,&M)!=EOF) 48 { 49 Build(1,N,1); 50 while(M--){ 51 scanf(" %c%d%d",&Str,&A,&B); 52 switch(Str){ 53 case 'Q':printf("%d\n",Query(A,B,1));break; 54 case 'U':UpDate_P(A,1,B);break; 55 } 56 } 57 } 58 return 0; 59 }
转载请备注:
**************************************
* 作者: Wurq
* 博客: https://www.cnblogs.com/Wurq/
* Gitee: https://gitee.com/wurq
**************************************
**************************************
* 作者: Wurq
* 博客: https://www.cnblogs.com/Wurq/
* Gitee: https://gitee.com/wurq
**************************************