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。
 
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;
}
View Code

修改: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 }
View Code

 更新模板: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 }
View Code

 

posted @ 2014-07-26 12:48  Wurq  阅读(170)  评论(0编辑  收藏  举报