题意:
解法:
补充说明:
假设最后的解是[l,r], 则[1,l-1]以及[r+1,n]一定是有序的.
想办法找到这个l-1和r+1:
我们可以维护有序的最大前缀和后缀.
对于中间无序的部分,求出mi和ma.
然后用mi筛掉前缀中必须排序的部分,
用ma筛掉后缀中必须排序的部分.
Code:
#include <bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define int long long
#define PI pair<int, int>
const int maxm=2e6+5;
const int mod=998244353;
int n;
int a[maxm];
struct STT{
int mi[maxm<<2];
int ma[maxm<<2];
void pushup(int k){
mi[k]=min(mi[k*2],mi[k*2+1]);
ma[k]=max(ma[k*2],ma[k*2+1]);
}
void update(int x,int val,int l,int r,int k){
if(l==r){
mi[k]=ma[k]=val;
return ;
}
int mid=(l+r)/2;
if(x<=mid)update(x,val,l,mid,k*2);
else update(x,val,mid+1,r,k*2+1);
pushup(k);
}
int ask(int st,int ed,int f/*是否求最小值*/,int l,int r,int k){
if(st<=l&&ed>=r){
return f?mi[k]:ma[k];
}
assert(l!=r);
int mid=(l+r)/2;
int ans=f?1e18:-1e18;
if(st<=mid){
if(f)ans=min(ans,ask(st,ed,f,l,mid,k*2));
else ans=max(ans,ask(st,ed,f,l,mid,k*2));
}
if(ed>mid){
if(f)ans=min(ans,ask(st,ed,f,mid+1,r,k*2+1));
else ans=max(ans,ask(st,ed,f,mid+1,r,k*2+1));
}
return ans;
}
void init(int l,int r,int k){
mi[k]=1e18;
ma[k]=1e18;
if(l==r)return ;
int mid=(l+r)/2;
init(l,mid,k*2);
init(mid+1,r,k*2+1);
}
}T;
set<int>st;
void query() {
if(!st.size()){
cout<<"-1 -1"<<endl;
return ;
}
int lc=*st.begin()-1;
int rc=*st.rbegin();
// 答案一定包含[lc,rc]
// cout<<lc<<' '<<rc<<endl;
// [1,lc]一定是有序的
// [rc,n]一定是有序的
int mi=T.ask(lc,rc,1,1,n,1);
int ma=T.ask(lc,rc,0,1,n,1);
// for(int i=1;i<=n;i++){
// cout<<T.ask(i,i,0,1,n,1)<<' ';
// }
// cout<<endl;
// cout<<"mi:"<<mi<<' '<<"ma:"<<ma<<endl;
//
int L=0;
int l=1,r=lc-1;
while(l<=r){
int mid=(l+r)/2;
if(a[mid]<=mi){
L=mid,l=mid+1;
} else {
r=mid-1;
}
}
//
int R=n+1;
l=rc+1,r=n;
while(l<=r){
int mid=(l+r)/2;
if(a[mid]>=ma){
R=mid,r=mid-1;
} else {
l=mid+1;
}
}
// cout<<"L:"<<L<<' '<<"R:"<<R<<endl;
L++;
R--;
if(L<R){
cout<<L<<' '<<R<<endl;
} else {
cout<<-1<<' '<<-1<<endl;
}
}
void solve(){
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
st.clear();
for(int i=2;i<=n;i++){
if(a[i]<a[i-1]){
st.insert(i);
}
}
T.init(1,n,1);
for(int i=1;i<=n;i++){
T.update(i,a[i],1,n,1);
}
// for(int i=1;i<=n;i++){
// cout<<T.ask(i,i,0,1,n,1)<<' ';
// }
// cout<<endl;
query();
int q;cin>>q;
while(q--){
int pos,x;cin>>pos>>x;
if(pos-1>=1&&a[pos]<a[pos-1]){
st.erase(pos);
}
if(pos+1<=n&&a[pos+1]<a[pos]){
st.erase(pos+1);
}
a[pos]=x;
if(pos-1>=1&&a[pos]<a[pos-1]){
st.insert(pos);
}
if(pos+1<=n&&a[pos+1]<a[pos]){
st.insert(pos+1);
}
T.update(pos,x,1,n,1);
query();
}
}
signed main() {
#define MULTI_CASE
ios::sync_with_stdio(0);
cin.tie(0);
#ifndef ONLINE_JUDGE
freopen("../in.txt", "r", stdin);
freopen("../out.txt", "w", stdout);
#endif
#ifdef MULTI_CASE
int T;
cin >> T;
while (T--)
#endif
solve();
return 0;
}