NC54357. 麦田守望者
描述
输入描述
第一行两个正整数n, q,分别表示麦穗的总数和操作的个数。
之后一行n个正整数,表示麦穗的权值。
接下来q行, 每行三个正整数表示一次操作。
输出描述
对每个询问,一行内输出一个整数代表答案。
示例1
输入:
5 3 1 2 3 4 5 2 1 5 1 2 4 2 1 5
输出:
3 5
C++11(clang++ 3.9) 解法, 执行用时: 660ms, 内存消耗: 10852K, 提交时间: 2020-03-08 11:56:38
#include <bits/stdc++.h> #define Lson left,mid,pos<<1 #define Rson mid+1,right,pos<<1|1 using namespace std; const int N = 5E5+3; const double e = 2.7182818; int a[N],Max[N<<2]; int build(int left,int right,int pos) { if(left==right) return Max[pos] = a[left]; int mid = (left+right)/2; return Max[pos] = max(build(Lson),build(Rson)); } int modify(int left,int right,int pos,int x,int val) { if(left>x||right<x) return Max[pos]; if(left==right) return a[left] = Max[pos] = val; int mid = (left+right)/2; return Max[pos] = max(modify(Lson,x,val),modify(Rson,x,val)); } int query(int left,int right,int pos,int qL,int qR) { if(qL>right||qR<left) return -1000000000; if(qL<=left&&right<=qR) return Max[pos]; int mid = (left+right)/2; return max(query(Lson,qL,qR),query(Rson,qL,qR)); } int Query(int left,int right,int pos,int qL,int qR,int v) { if(left>qR||right<qL||Max[pos]<=v) return 10000000; //不在所求的范围之内 if(left==right) return left; int mid = (left+right)/2; if(qL<=left&&right<=qR) { if(Max[pos<<1]>v) return Query(left,mid,pos<<1,qL,qR,v); else return Query(mid+1,right,pos<<1|1,qL,qR,v); } int idL = Query(left,mid,pos<<1,qL,qR,v); int idR = Query(mid+1,right,pos<<1|1,qL,qR,v); return min(idL,idR); } int main() { int n,q,x,v,l,r,op,m,Lmax,Rmax,id; scanf("%d%d",&n,&q); for(int i=1;i<=n;++i) scanf("%d",a+i); build(1,n,1); while(q--) { scanf("%d",&op); if(op==1) { scanf("%d%d",&x,&v); modify(1,n,1,x,v); } else { scanf("%d%d",&l,&r); if(l==r) { printf("%d\n",a[r]);continue; } m = l+floor(1.0*(r-l+1)/e); Lmax = query(1,n,1,l,m); Rmax = query(1,n,1,m+1,r); if(Rmax<=Lmax) id = r; else id = Query(1,n,1,m+1,r,Lmax); printf("%d\n",a[id]); } } return 0; }