最大值

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 }

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

原文地址:https://www.cnblogs.com/rax-/p/9056927.html