问题 B: 分数修改
时间限制: 1 Sec 内存限制: 128 MB题目描述
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生感到反感,不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
输入
本题目包含多组测试,请处理到文件结束。在每个测试的第一行,有两个正整数 N 和 M分别代表学生的数目和操作的数目。学生ID编号分别从1编到N。第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数ai代表ID为i的学生的成绩。接下来有M行。每一行有一个字符 C (只取'Q'或'U') ,和两个正整数A,B。当C为'Q'的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。
输出
输出相应的询问。
样例输入
5 61 2 3 4 5Q 1 5U 3 6Q 3 4Q 4 5U 2 9Q 1 5
样例输出
5659
提示
【数据说明】
对于 30%的数据,0 < n < 1,00,0 < m < 10,00;
对于 60%的数据,0 < n < 1,000,0 < m < 1000;
对于 100%的数据,0 < n < 200,000,0 < m < 50000,0 <=ai<=2^31-1。
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
int data[200001];
struct node
{
int start,end;
int max;
int left,right;
};
node tree[400002];
int cnt=0;
int fillnode(int leftbound,int rightbound)
{
//if(leftbound>rightbound) throw "d";
tree[cnt].start=leftbound;
tree[cnt].end=rightbound;
tree[cnt].max=-1;
if(leftbound==rightbound)
{
tree[cnt].left=-1;
tree[cnt].right=-1;
cnt++;
return cnt-1;
}
cnt++;
int cur=cnt-1;
tree[cur].left=fillnode(leftbound,(leftbound+rightbound)/2);
tree[cur].right=fillnode((leftbound+rightbound)/2+1,rightbound);
return cur;
}
void change(int targetpos,int value,int nodepos)
{
#if 0
printf("%d %d %d\n",targetpos,value,nodepos);
#endif //
if(value>tree[nodepos].max)
{
tree[nodepos].max=value;
}
if(tree[nodepos].left==-1)
{
/// reach this point
tree[nodepos].max=value;
return;
}
if(targetpos<=tree[tree[nodepos].left].end)
{
change(targetpos,value,tree[nodepos].left);
}
else
{
change(targetpos,value,tree[nodepos].right);
}
}
int findmax(int leftbound,int rightbound,int nodepos)
{
if(tree[nodepos].left==-1)
{
return tree[nodepos].max;
}
if(rightbound<=tree[tree[nodepos].left].end)
{
/// Full left
return findmax(leftbound,rightbound,tree[nodepos].left);
}
if(leftbound>=tree[tree[nodepos].right].start)
{
/// Full right
return findmax(leftbound,rightbound,tree[nodepos].right);
}
/// Half left and half right
int leftmax=findmax(leftbound,tree[tree[nodepos].left].end,tree[nodepos].left);
int rightmax=findmax(tree[tree[nodepos].right].start,rightbound,tree[nodepos].right);
return leftmax>rightmax?leftmax:rightmax;
}
char buff[8];
int eax,ebx;
int main()
{
fillnode(1,200000);
int n,m;
while(scanf("%d %d",&n,&m)==2)
{
for(int i=1;i<=n;i++)
{
scanf("%d",&data[i]);
change(i,data[i],0);
}
for(int i=0;i<m;i++)
{
scanf("%s %d %d",buff,&eax,&ebx);
switch(buff[0])
{
case 'U':
change(eax,ebx,0);
break;
case 'Q':
/// Find Max from [eax,ebx]
int ans=findmax(eax,ebx,0);
printf("%d\n",ans);
break;
}
}
for(int i=0;i<200001;i++)
{
/// Reset the tree.
tree[i].max=-1;
}
}
return 0;
}
总之先码着= = 大坑以后填>_<
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
long score[200001];
char ppp[4];
int main()
{
int n,m;
while(scanf("%d %d",&n,&m)==2)
{
for(int i=1; i<=n; i++)
{
scanf("%ld",&score[i]);
}
long eax,ebx;
for(int q=0; q<m; q++)
{
scanf("%s %ld %ld",ppp,&eax,&ebx);
switch(ppp[0])
{
case 'U':
score[eax]=ebx;
break;
case 'Q':
long max=-1;
for(int i=eax; i<=ebx; i++)
{
if(max<score[i])
{
max=score[i];
}
}
printf("%ld\n",max);
break;
}
}
}
return 0;
}