zoukankan      html  css  js  c++  java
  • HDU-1754

    I Hate It

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


    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
    Hint
    Huge input,the C function scanf() will work better than cin
     
    Author
    linle
     
    Source
    分块
     1 #include <bits/stdc++.h>
     2 #define lid id<<1
     3 #define rid id<<1|1
     4 #define maxn 200005
     5 using namespace std;
     6 int blo[maxn],stu[maxn],vis[maxn],l[maxn],r[maxn];
     7 int n,m,num;
     8 void build()
     9 {
    10     num=sqrt(n);
    11     if(n%num!=0) num++;
    12     for(int i=1;i<=n;i++) scanf("%d",&stu[i]);
    13     for(int i=1;i<=n;i++)
    14     {
    15         blo[i]=(i-1)/num+1;
    16         vis[blo[i]]=max(vis[blo[i]],stu[i]);
    17     }
    18     for(int i=1;i<=num;i++)
    19     {
    20         l[i]=(i-1)*num+1;
    21         r[i]=i*num;
    22     }
    23     r[blo[n]]=n;
    24 }
    25 void update(int cnt)
    26 {
    27     int flag=blo[cnt];
    28     vis[flag]=0;
    29     for(int i=l[flag];i<=r[flag];i++)
    30     {
    31         vis[flag]=max(vis[flag],stu[i]);
    32     }
    33 }
    34 int query(int ls,int rs)
    35 {
    36     if(blo[ls]==blo[rs])
    37     {
    38         int ans=0;
    39         for(int i=ls;i<=rs;i++)
    40         {
    41             ans=max(ans,stu[i]);
    42         }
    43         return ans;
    44     }
    45     else
    46     {
    47         int ans=0;
    48         for(int i=ls;i<=r[blo[ls]];i++)
    49         {
    50             ans=max(ans,stu[i]);
    51         }
    52         for(int i=blo[ls]+1;i<=blo[rs]-1;i++)
    53         {
    54             ans=max(ans,vis[i]);
    55         }
    56         for(int i=l[blo[rs]];i<=rs;i++)
    57         {
    58             ans=max(ans,stu[i]);
    59         }
    60         return ans;
    61     }
    62 }
    63 int main()
    64 {
    65     while(~scanf("%d%d",&n,&m))
    66     {
    67         memset(vis,0,sizeof(vis));
    68         build();
    69         char ch[5];
    70         while(m--)
    71         {
    72             int a,b;
    73             scanf("%s",ch);
    74             scanf("%d%d",&a,&b);
    75             if(ch[0]=='U')
    76             {
    77                 stu[a]=b;
    78                 update(a);
    79             }
    80             else
    81             {
    82                 printf("%d
    ",query(a,b));
    83             }
    84         }
    85     }
    86     return 0;
    87 }
    View Code

    线段树

     1 #include <bits/stdc++.h>
     2 #define lid id<<1
     3 #define rid id<<1|1
     4 #define maxn 200005
     5 using namespace std;
     6 struct node
     7 {
     8     int l,r,scr;
     9 };
    10 node stu[maxn*4];
    11 int s[maxn];
    12 
    13 void push_up(int id)
    14 {
    15     stu[id].scr=max(stu[lid].scr,stu[rid].scr);
    16 }
    17 void build(int id,int l,int r)
    18 {
    19     stu[id].l=l;stu[id].r=r;
    20     if(l==r)
    21     {
    22         stu[id].scr=s[l];
    23         return ;
    24     }
    25     int mid=(l+r)>>1;
    26     build(lid,l,mid);
    27     build(rid,mid+1,r);
    28     push_up(id);
    29 }
    30 void update(int id,int cnt,int change)
    31 {
    32     if(cnt<stu[id].l||cnt>stu[id].r)    return ;
    33     if(cnt==stu[id].l&&cnt==stu[id].r)
    34     {
    35         stu[id].scr=change;
    36         return ;
    37     }
    38     int mid=(stu[id].l+stu[id].r)>>1;
    39     if(cnt<=mid) update(lid,cnt,change);
    40     else update(rid,cnt,change);
    41     push_up(id);
    42 }
    43 int query(int id,int l,int r)
    44 {
    45     if(l<=stu[id].l&&r>=stu[id].r)
    46     {
    47         return stu[id].scr;
    48     }
    49     int mid=(stu[id].l+stu[id].r)>>1;
    50     if(r<=mid) return query(lid,l,r);
    51     else if(l>mid) return query(rid,l,r);
    52     else return max(query(lid,l,mid),query(rid,mid+1,r));
    53 }
    54 int main()
    55 {
    56     int n,m;
    57     while(~scanf("%d%d",&n,&m))
    58     {
    59         for(int i=1;i<=n;i++) scanf("%d",&s[i]);
    60         build(1,1,n);
    61         char ch[5];
    62         while(m--)
    63         {
    64             int a,b;
    65             scanf("%s",ch);
    66             scanf("%d%d",&a,&b);
    67             if(ch[0]=='Q')
    68                 printf("%d
    ",query(1,a,b));
    69             else update(1,a,b);
    70         }
    71     }
    72     return 0;
    73 }
    View Code
  • 相关阅读:
    作业十三
    作业十二
    第十一次作业
    编译原理第十次作业
    P3388 【模板】割点(割顶) 题解 (Tarjan)
    BuaacodingT141 microhhh的回城 题解(模拟)
    P2055 [ZJOI2009]假期的宿舍 题解(二分图)
    P2764 最小路径覆盖问题 题解(二分图)
    2019.2-2019.3 TO-DO LIST
    P3369 【模板】普通平衡树 题解(Splay/FHQ)
  • 原文地址:https://www.cnblogs.com/mile-star/p/10536640.html
Copyright © 2011-2022 走看看