- 基本介绍
- 模板题目
- 代码实现
基本介绍
在求区间最值的基础上加了一个单点修改 也就是下面代码中的update函数 主要通过不断二分区间往下找左右子区间 直到一个子区间只包括一个节点 直接改变这个节点的值并改变所有与这个点相关的父亲节点 (摘自战友Jiang.S博客)
模板题目
题目描述
给出N个数,两种操作:
1、C x y:修改第x个数的值为y;
2、P x y:求第x到第y个的最大值,注:x未必比y小
输入输出格式
输入格式:
第一行输入N和M,N表示有N个数(N<=200000,M<5000),M表示有M个操作
下来N个数
然后是M个操作。
输出格式:
遇到P操作的时候,输出结果。
输入输出样例
输入样例:
5 6
1 2 3 4 5
P 1 5
C 3 6
P 3 4
P 4 5
C 2 9
P 1 5
输出样例:
5
6
5
9
代码实现
#include<iostream>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<string>
using namespace std;
#define in = read()
typedef long long ll;
const ll size = + ;
#define left (rt<<1)
#define right (rt<<1|1)
#define mid ((l + r)>>1)
#define lson l,mid,left
#define rson mid + 1,r,right
#define len (r - l + 1)
ll n,m;
ll tree[size];
inline ll read(){
ll num = , f = ; char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') f = -;
ch = getchar();
}
while(isdigit(ch)){
num = num* + ch - '0';
ch = getchar();
}
return num*f;
}
inline void pushup1(ll rt){ tree[rt] = max(tree[left] , tree[right]);}
void buildtree(ll l, ll r, ll rt){
if(l == r){ tree[rt] in; return;}
buildtree(lson); buildtree(rson); pushup1(rt);
}
ll query(ll from,ll to,ll l,ll r,ll rt){
if(from <= l && to >= r) return tree[rt];
ll ans = ;
if(from <= mid) ans = max(ans , query(from,to,lson));
if(to > mid) ans = max(ans , query(from,to,rson));
return ans;
}
void update(ll num,ll dis,ll l,ll r,ll rt){
if(l == r){ tree[rt] = dis; return;}
if(num <= mid) update(num,dis,lson);
else update(num,dis,rson);
pushup1(rt);
}
int main(){
n in; m in;
buildtree(,n,);
for(int i=;i<=m;i++){
string s; cin>>s;
ll x,y; x in; y in;
if(s[] == 'P'){
if(x <= y)
printf("%lld\n",query(x,y,,n,));
if(y < x)
printf("%lld\n",query(y,x,,n,));
}
else if(s[] == 'C')
update(x,y,,n,);
}
}
//COYG