hdu 1754 I Hate It

来源:互联网 发布:中国最大源码网站 编辑:程序博客网 时间:2024/06/12 22:41

I Hate It

Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 37627    Accepted Submission(s): 14893


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 61 2 3 4 5Q 1 5U 3 6Q 3 4Q 4 5U 2 9Q 1 5
 

Sample Output
5659
Hint
Huge input,the C function scanf() will work better than cin
 
线段树(区间最值):

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int max(int a,int b){    return (a>b?a:b);}int a[200000];struct Node{    int left,right;    int t;}node[4*200000];void MakeTree(int l,int r,int i){  node[i].left=l;  node[i].right=r;   if(l==r)   {       node[i].t=a[l];       return ;   }  int mid=(l+r)/2;  MakeTree(l,mid,2*i);  MakeTree(mid+1,r,2*i+1);  node[i].t=max(node[2*i].t,node[2*i+1].t);}void UpdateTree(int i,int x,int y){    int l=node[i].left;    int r=node[i].right;    int mid=(l+r)/2;    if(x==l&&x==r)    {        node[i].t=y;        return ;    }    if(x>mid)        UpdateTree(2*i+1,x,y);    else        UpdateTree(2*i,x,y);    node[i].t=max(node[2*i].t,node[2*i+1].t);}int QueryTree(int x,int y,int i){    if(node[i].left==x && node[i].right==y)        return node[i].t;    //if(node[i].left==node[i].right)        //return 0;    int m=(node[i].left+node[i].right)/2;    if(x>m)        return QueryTree(x,y,2*i+1);    else if(y<=m)        return QueryTree(x,y,2*i);    else        return  max(QueryTree(x,m,2*i),QueryTree(m+1,y,2*i+1));}int main (){    int T,n,m;    int i,j,x,y;    char c[10];    while(~scanf("%d%d",&n,&m))    {               for(i=1;i<=n;i++)            scanf("%d",&a[i]);        MakeTree(1,n,1);        getchar();        for(j=1;j<=m;j++)        {         scanf("%c%d%d",&c[0],&x,&y);         getchar();         if(c[0]=='U')            UpdateTree(1,x,y);         else            cout<<QueryTree(x,y,1)<<endl;       }    }    return 0;}



树状数组:

#include<cstdio>#include<iostream>#include<cstring>using namespace std;int a[200005],p[200005];int n;int lowbit(int t){    return t&(-t);}void Change(){    int i,j;    for(i=1;i<=n;i++)    {        p[i]=a[i];        for(j=1;j<lowbit(i);j=j*2)        {           if(p[i]<p[i-j])              p[i]=p[i-j];        }    }}void Update(int t,int d){    a[t]=d;    while(t<=n)    {       if(p[t]<d)         p[t]=d;       else         break;       t+=lowbit(t);    }}int Getmax(int l,int r){    int ans=a[r];    while(1)    {        if(ans<a[r])            ans=a[r];        if(l==r) break;        for(r=r-1;r-l>=lowbit(r);r=r-lowbit(r))        {            if(ans<p[r])              ans=p[r];        }    }    return ans;}int main (){    int m,i,j;    int x,y;    char c[10];    while(~scanf("%d%d",&n,&m))    {       memset(p,0,sizeof(p));       for(i=1;i<=n;i++)       scanf("%d",&a[i]);       Change();       for(j=1;j<=m;j++)       {        scanf("%s%d%d",c,&x,&y);        if(c[0]=='U')         Update(x,y);        else         printf("%d\n",Getmax(x,y));       }    } return 0;}






3 0
原创粉丝点击