I Hate It
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 60417 Accepted Submission(s): 23517
這讓很多學生很反感。
不管你喜不喜歡,現在需要你做的是,就是按照老師的要求,寫一個程序,模擬老師的詢問。當然,老師有時候需要更新某位同學的成績。
在每個測試的第一行,有兩個正整數 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。
#include <iostream>
#include <stdio.h>
#include <string>
#include <cstring>
#include <algorithm>
#include <cmath>
#define ll __int64
using namespace std;
ll a[200009*4]; //大約是4倍點的空間
void buildtree(int le,int ri,int num)
{
if(le==ri)
{
scanf("%I64d",&a[num]);
return;
}
int mid=(le+ri)/2;
buildtree(le,mid,num*2);
buildtree(mid+1,ri,num*2+1);
a[num]=max(a[num],a[num*2]); //寫法問題,注意將a數組初始化爲全0
a[num]=max(a[num],a[num*2+1]);
}
ll query(int le,int ri,int num,int x,int y)
{
if(x<=le && y>=ri)
{
return a[num];
}
int mid=(le+ri)/2;
ll ans=0;
if(x<=mid)
ans=max(ans,query(le,mid,num*2,x,y));
if(y>mid) //不可以取等號,因爲下次要去的區間是[mid+1,ri],不包括mid這個值
ans=max(ans,query(mid+1,ri,num*2+1,x,y));
return ans;
}
void add(int le,int ri,int num,int x,int y)
{
if(le==ri)
{
a[num]=y;
return;
}
int mid=(le+ri)/2;
if(x<=mid)
add(le,mid,num*2,x,y);
else
add(mid+1,ri,num*2+1,x,y);
a[num]=max(a[num],a[num*2]);
a[num]=max(a[num],a[num*2+1]);
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(a,0,sizeof a); //初始化!!!
buildtree(1,n,1);
scanf("%d",&m);
char s[10];
int x,y;
while(m--)
{
scanf("%s %d %d",s,&x,&y);
if(s[0]=='Q')
{
printf("%I64d\n",query(1,n,1,x,y));
}
else
{
add(1,n,1,x,y);
}
}
}
return 0;
}