• 最大值


    1. 最大值(max.cpp/in/out)

    题目描述

    在N(1<=N<=100000)个数A1…An 组成的序列上进行M(1<=M<=100000)次操作,操作有两种: (1)1 x

    y:表示修改A[x]为y; (1)2 x y:询问x 到y 之间的最大值。

    输入

    第一行输入N(1<=N<=100000),表示序列的长度,接下来N 行输入原始序列;接下来一行输入

    M(1<=M<=100000)表示操作的次数,接下来M 行,每行为1 x y 或2 x y

    输出

    对于每个操作(2)输出对应的答案。

    样例输入

    5

    1

    2

    3

    4

    5

    3

    2 1 4

    1 3 5

    2 2 4

    样例输出

    4

    5

    ****考试的写的答案有种翻译的感觉。。。他咋说我就咋做的。

     1 #include<iostream>
     2 #include<fstream>
     3 #include<algorithm>
     4 using namespace std;
     5 int n,M,line[100010][3],maxn=0,x[100010],ans[100010]={0};
     6 struct treenode
     7 {
     8     int b;int e;   //b表示树的左端点,e表示树的右端点 
     9     int mn;       //mn表示这个区间内的最大值 
    10 }tree[400010];
    11 void inittree(int l,int r,int p)  //此乃建树的过程 
    12 {
    13     int m;
    14     tree[p].b=l;
    15     tree[p].e=r;
    16     if(l==r)tree[p].mn=x[l];
    17     else
    18     {
    19         m=(l+r)>>1;
    20         inittree(l,m,p+p);
    21         inittree(m+1,r,p+p+1);
    22         tree[p].mn=max(tree[p+p].mn,tree[p+p+1].mn);
    23     }
    24 }
    25 void ins(int np,int nn,int p)
    26 {
    27     int m;
    28     if(tree[p].b==tree[p].e)tree[p].mn=nn;   //如果这个区间只有他自己个 那么这个区间的最大值就是改后的这个数 
    29     else
    30     {
    31         m=(tree[p].b+tree[p].e)>>1;
    32         if(np<=m)ins(np,nn,p+p);  //通过判断大小来搜索他的左儿子或右儿子 
    33         else ins(np,nn,p+p+1);
    34         tree[p].mn=max(tree[p+p].mn,tree[p+p+1].mn);  //他的最大值就是他左儿子和右儿子的最大值 
    35     }
    36 }
    37 int calc(int p,int st,int en)
    38 {
    39     int m;
    40     if(tree[p].b==st&&tree[p].e==en)
    41     return tree[p].mn;  //如果他的左端点等于x右端点等于y这就是要求的那个区间返回他的最大值即可 
    42     if(tree[p].b==tree[p].e)
    43     return tree[p].mn;  //如果这个区间只有自己那么输出他即可 
    44     else
    45     {
    46         m=(tree[p].b+tree[p].e)>>1;  //通过二分的方法寻找想要求的区间段 
    47         if(en<=m)return calc(p+p,st,en); 
    48         if(st>m)return calc(p+p+1,st,en);
    49         return max(calc(p+p,st,m),calc(p+p+1,m+1,en));  //返回的最大值就是他的左儿子和右儿子的最大值 
    50     }
    51 }
    52 void addans(int answer)
    53 {
    54     ans[0]++;
    55     ans[ans[0]]=answer;  //把答案存进数组里面 
    56 }
    57 int main()
    58 {
    59     int i,j;
    60     cin>>n;
    61     for(i=1;i<=n;i++)
    62     scanf("%d",&x[i]);
    63     inittree(1,n,1);  //建树 
    64     cin>>M;
    65     for(i=1;i<=M;i++)
    66     {
    67         int temp,tx,ty;
    68         scanf("%d %d %d",&temp,&tx,&ty);
    69         if(temp==1)
    70         {
    71             ins(tx,ty,1);  //更改 
    72         }
    73         if(temp==2)
    74         addans(calc(1,tx,ty));  //calc求区间最大值 ,addans存答案 
    75     }
    76     for(i=1;i<=ans[0];i++)  //输出答案 
    77     printf("%d
    ",ans[i]);
    78     return 0;
    79 }

    ****这道题要用线段树做,线段树里有一坨的二分。

  • 相关阅读:
    css 标签 清除浮动
    css 标签 垂直居中
    getResource().getPath()返回的路径空格变成了 %20
    css3颜色渐变
    网页动画结束判断事件
    手机端js事件支持(event)
    手机端js实现滑块推动
    手机端js模拟长按事件(代码仿照jQuery)
    基于SOA架构---ServiceProxy定义
    对SSL加密通信安全的理解
  • 原文地址:https://www.cnblogs.com/rax-/p/9056927.html
Copyright © 2020-2023  润新知