zoukankan      html  css  js  c++  java
  • I Hate It HDU

    很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。 
    这让很多学生很反感。 

    不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。

    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

    思路:根据线段树的算法首先是正常建立树,然后修改时时间应该值完全变成另一个值,查询时返回大的不再是和而是最大值。

    代码:
      1 #include <cstdio>
      2 #include <fstream>
      3 #include <algorithm>
      4 #include <cmath>
      5 #include <deque>
      6 #include <vector>
      7 #include <queue>
      8 #include <string>
      9 #include <cstring>
     10 #include <map>
     11 #include <stack>
     12 #include <set>
     13 #include <sstream>
     14 #include <iostream>
     15 #define mod 998244353
     16 #define eps 1e-6
     17 #define ll long long
     18 #define INF 0x3f3f3f3f
     19 using namespace std;
     20 
     21 
     22 struct node
     23 {
     24     //l表示左边,r表示右边,sum表示该线段的值
     25     int l,r,sum;
     26 };//数据一般是点数的十倍
     27 node no[2000000];
     28 
     29 //存放每个点的值
     30 int number[200000];
     31 
     32 //初始化
     33 //k表示当前节点的编号,l表示当前区间的左边界,r表示当前区间的右边界
     34 void build(int k,int l,int r)
     35 {
     36     no[k].l=l;
     37     no[k].r=r;
     38     //如果递归到最低点
     39     if(l==r)
     40     {
     41         //赋值并记录该点对应的节点编号
     42         no[k].sum=number[l];
     43         return ;
     44     }
     45     //对半分
     46     int mid=(l+r)/2;
     47     //递归到左线段
     48     build(k*2,l,mid);
     49     //递归到右线段
     50     build(k*2+1,mid+1,r);
     51     //用左右线段的值更新该线段的值
     52     no[k].sum=max(no[k*2].sum,no[k*2+1].sum);
     53 }
     54 //改边指定节点标号的值
     55 //k表示当前节点的编号,要把节点x的sum值变成y
     56 void change(int k,int x,int y)
     57 {
     58     if(no[k].l==no[k].r)
     59     {
     60         no[k].sum=y;
     61         return ;
     62     }
     63     int mid =(no[k].l+no[k].r)/2;
     64     //递归到左线段
     65     if(x<=mid)
     66     {
     67         change(k*2,x,y);
     68     }
     69     else//递归到右线段
     70     {
     71         change(k*2+1,x,y);
     72     }
     73     //用左右线段的值更新该线段的值
     74     no[k].sum=max(no[k*2].sum,no[k*2+1].sum);
     75 }
     76 //查询指定区间内的所有的和
     77 //k表示当前节点的编号,l表示当前区间的左边界,r表示当前区间的右边界
     78 int query(int k,int l,int r)
     79 {
     80     //如果当前区间就是询问区间,完全重合,那么显然可以直接返回
     81     if(no[k].l==l&&no[k].r==r)
     82     {
     83         return no[k].sum;
     84     }
     85     //取中值
     86     int mid = (no[k].l+no[k].r)/2;
     87     //如果询问区间包含在左子区间中
     88     if(r<=mid)
     89     {
     90         return query(k*2,l,r);
     91     }
     92     else if(l>mid)//如果询问区间包含在右子区间中
     93     {
     94         return query(k*2+1,l,r);
     95     }
     96     else//如果询问区间跨越两个子区间
     97     {
     98         return max(query(k*2,l,mid),query(k*2+1,mid+1,r));
     99     }
    100 }
    101 int main()
    102 {
    103     int n,m;
    104     while(scanf("%d %d",&n,&m)!=EOF)
    105     {
    106         //每个测试样例前都应该初始化数据
    107         memset(no,0,sizeof(no));
    108         memset(number,0,sizeof(number));
    109         
    110         for(int i=1;i<=n;i++)
    111         {
    112             scanf("%d",&number[i]);
    113         }
    114         //初始化树
    115         build(1,1,n);
    116         string str;
    117         int a,b;
    118         for(int i=0;i<m;i++)
    119         {
    120             cin>>str>>a>>b;
    121             if(str[0]=='Q')
    122             {
    123                 printf("%d
    ",query(1,a,b));
    124             }
    125             if(str[0]=='U')
    126             {
    127                 change(1,a,b);
    128             }
    129         }
    130     }
    131     
    132 }
  • 相关阅读:
    网站备份list
    vnc checklist
    appnode iptables 规则后面覆盖前面的
    Appnode + Discuz checklist
    解决WORD文档无法显示链接的图像问题
    应用容器Application container
    要研究的内容
    转 Flex MXML编译成AS类
    Flex文件结构
    int a
  • 原文地址:https://www.cnblogs.com/mzchuan/p/11759109.html
Copyright © 2011-2022 走看看