精卫填海
线段树更新时,更新最大值,查询时,添加几个条件,第一 查看标记看是否找到,第二 如果值小于要找的值 返回,第三 二分查找时判断一下左子树和右子树的最大值是否大于s;
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 250000 + 5;
int tree[maxn << 2];
int n;
void build(int l,int r, int rt){
if(l == r){
scanf("%d",&tree[rt]);
return ;
}
int mid = (l + r) >> 1;
build(l,mid,rt << 1);
build(mid + 1, r, rt <<1|1);
tree[rt] = max(tree[rt <<1],tree[rt<<1|1] );
return ;
}
void update(int pos,int val, int l,int r,int rt){
if(l == r){
tree[rt] = val;
return ;
}
int mid = (l + r) >> 1;
if(pos <= mid) update(pos, val,l,mid,rt << 1);
else update(pos , val, mid + 1,r , rt <<1|1);
tree[rt] = max(tree[rt << 1],tree[rt <<1|1]);
}
int flag = 0;
void query(int L,int R, int l,int r,int rt,int s){
if(L<=l&&r <= R){
if(flag) return ;
if(tree[rt] < s) return;
if(l == r){
if(!flag){
printf("%d\n",l);
flag = 1;
tree[rt] = 0;
}
return ;
}
}
int mid = (l + r) >> 1;
if(L<=mid&&tree[rt<<1]>s) query(L,R, l, mid, rt << 1,s);
if(mid<=R&&tree[rt<<1|1]>s)query(L,R, mid + 1, r, rt << 1|1,s);
return ;
}
int main()
{
int m;
scanf("%d%d",&n,&m);
build(1,n,1);
while(m--){
int c,k,s;
scanf("%d%d%d",&c,&k,&s);
if(c == 1){
query(k + 1, n,1,n,1, s);
if(!flag) printf("-1\n");
flag = 0;
}
else{
update(k,s,1,n,1);
}
}
}