2018.4.1
愚人节!!!
就在这样一个节日中,我过了萝卜生中的第200题!!!
因为之前没发觉我已经200T了,所以没有截图!!!啊!博客也是过了两天才写的。
。。。
T200
题面
给定一个包含n个数的序列,初值全为0,现对这个序列有两种操作:
操作1:把 给定 第k1 个数改为k2;
操作2:查询 从第k1个数到第k2个数得最大值。(k1<=k2<=n)
所有的数都 <=100000
输入格式
第一行给定一个整数n,表示有n个操作。
以下接着n行,每行三个整数,表示一个操作。
第一个树表示操作序号,第二个数为k1,第三个数为k2
输出格式
若干行,查询一次,输出一次。
样例数据
input
3
1 2 2
1 3 3
2 2 3
output
3
解析
线段树模版题啊
就是线段树的单点修改和求区间最值。
具体解析会在线段树详解。
代码
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int num=0,flag=1;
char c=getchar();
for(;c<'0'||c>'9';c=getchar())
if (c=='-') flag=-1;
for(;c>='0'&&c<='9';c=getchar())
num=(num<<1)+(num<<3)+c-48;
return num*flag;
}
int n,k,k1,k2;
int tree[500010]={};
void change(int root,int l,int r)
{
int mid=(l+r)/2;
if (l==r) tree[root]=k2;
else
{
if (k1<=mid) change(root*2,l,mid);
else change(root*2+1,mid+1,r);
tree[root]=max(tree[root*2],tree[root*2+1]);
}
}
int makemax(int root,int l,int r)
{
int mid=(l+r)/2,ans=-100000000;
if (l>=k1&&r<=k2) return tree[root];
if (k1<=mid) ans=max(ans,makemax(root*2,l,mid));
if (k2>mid) ans=max(ans,makemax(root*2+1,mid+1,r));
return ans;
}
int main()
{
n=read();
for(int i=1;i<=n;++i)
{
k=read();k1=read();k2=read();
if (k==1)
change(1,1,n);
else printf("%d\n",makemax(1,1,n));
}
return 0;
}