传送门
题意:
给出两个长度为NNN的整数序列A1A2...ANA_1A_2...A_NA1A2...AN,B1B2...BNB_1B_2...B_NB1B2...BN。有MMM组询问(opt,l,r,d)(opt,l,r,d)(opt,l,r,d),令n=r−l+1n=r-l+1n=r−l+1
若opt=Aopt=Aopt=A:∀i∈[1,n],ai=Al+i−1+d,bi=Bl+i−1\forall i\in[1,n],a_i=A_{l+i-1}+d,b_i=B_{l+i-1}∀i∈[1,n],ai=Al+i−1+d,bi=Bl+i−1
若opt=Bopt=Bopt=B:∀i∈[1,n],ai=Al+i−1,bi=Bl+i−1+d\forall i\in[1,n],a_i=A_{l+i-1},b_i=B_{l+i-1}+d∀i∈[1,n],ai=Al+i−1,bi=Bl+i−1+d
求min(max{a1,a2,...,ap,bp+1,bp+2,...,bn}∣0≤p≤n)min(max\{a_1,a_2,...,a_p,b_{p+1},b_{p+2},...,b_n\}|0\leq p\leq n)min(max{a1,a2,...,ap,bp+1,bp+2,...,bn}∣0≤p≤n)
题解:
记maxa=max{a1,a2,...,ap}max_a=max\{a_1,a_2,...,a_p\}maxa=max{a1,a2,...,ap},随着ppp的增大,maxamax_amaxa单调不降。
记maxb=max{bp+1,bp+2,...,bn}max_b=max\{b_{p+1},b_{p+2},...,b_n\}maxb=max{bp+1,bp+2,...,bn},随着ppp的增大,maxbmax_bmaxb单调不升。
max(maxa,maxb)max(max_a,max_b)max(maxa,maxb)一定先不升,再不降,因此最优的ppp可以二分得到:
若p=midp=midp=mid时,
- maxa>maxbmax_a>max_bmaxa>maxb,那么最优的ppp在[l,mid][l,mid][l,mid]中;
- maxa≤maxbmax_a\leq max_bmaxa≤maxb,那么最优的ppp在[mid+1,r][mid+1,r][mid+1,r]中。
可以用线段树上二分来得到最优的ppp。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pr;
#define FR first
#define SE second
namespace IO{char buf[1000010],*cur=buf+1000010;inline char getc(){(cur==buf+1000010)?fread(cur=buf,1,1000010,stdin):0;return *cur++;}char buff[1000010],*curr=buff;inline void flush(){fwrite(buff,1,curr-buff,stdout);}inline void putc(const char &ch){(curr==buff+1000010)?fwrite(curr=buff,1,1000010,stdout):0;*curr++=ch;}inline void rd(int &x){x=0;char ch=getc();int f=1;while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}x*=f;}char st[60];int tp;void PT(int x){if(x==0)putc('0');else{if(x<0){putc('-');x=-x;}while(x>0){st[++tp]=x%10+'0';x/=10;}}while(tp)putc(st[tp--]);}
}
using IO::getc;
using IO::putc;
using IO::rd;
using IO::PT;
int n,q;
const int N=1000010;
int maxa[N<<2],maxb[N<<2],tga[N<<2],tgb[N<<2];
int A[N],B[N];
void pushup(int u){maxa[u]=max(maxa[u<<1],maxa[u<<1|1]);maxb[u]=max(maxb[u<<1],maxb[u<<1|1]);
}
void Add(int u,int x,int y){maxa[u]+=x;maxb[u]+=y;tga[u]+=x;tgb[u]+=y;
}
void pushdown(int u){Add(u<<1,tga[u],tgb[u]);Add(u<<1|1,tga[u],tgb[u]);tga[u]=tgb[u]=0;
}
void build(int u,int l,int r){if(l==r){maxa[u]=A[l];maxb[u]=B[l];return;}int mid=(l+r)>>1;build(u<<1,l,mid);build(u<<1|1,mid+1,r);pushup(u);
}
void update(int u,int l,int r,int L,int R,int d,bool ty){if(l==L&&r==R){if(ty) Add(u,d,0);else Add(u,0,d);return;}pushdown(u);int mid=(l+r)>>1;if(R<=mid) update(u<<1,l,mid,L,R,d,ty);else if(mid<L) update(u<<1|1,mid+1,r,L,R,d,ty);else{update(u<<1,l,mid,L,mid,d,ty);update(u<<1|1,mid+1,r,mid+1,R,d,ty);}pushup(u);
}
pr ans[N<<2];
void pre(int u,int l,int r,int L,int R){if(l==L&&r==R){ans[u]=pr(maxa[u],maxb[u]);return;}pushdown(u);int mid=(l+r)>>1;if(R<=mid){pre(u<<1,l,mid,L,R);ans[u]=ans[u<<1];}else if(mid<L){pre(u<<1|1,mid+1,r,L,R);ans[u]=ans[u<<1|1];}else{pre(u<<1,l,mid,L,mid);pre(u<<1|1,mid+1,r,mid+1,R);ans[u].FR=max(ans[u<<1].FR,ans[u<<1|1].FR);ans[u].SE=max(ans[u<<1].SE,ans[u<<1|1].SE);}
}
int solve(int u,int l,int r,int L,int R){if(l==L&&r==R){if(l==r) return min(maxa[u],maxb[u]);int mid=(l+r)>>1;pushdown(u);int s1=maxa[u<<1],s2=maxb[u<<1|1];if(s1>s2) return min(s1,max(s2,solve(u<<1,l,mid,l,mid)));else return min(s2,max(s1,solve(u<<1|1,mid+1,r,mid+1,r)));} int mid=(l+r)>>1;if(R<=mid) return solve(u<<1,l,mid,L,R);else if(mid<L) return solve(u<<1|1,mid+1,r,L,R);else{int s1=ans[u<<1].FR,s2=ans[u<<1|1].SE;if(s1>s2) return min(s1,max(s2,solve(u<<1,l,mid,L,mid)));else return min(s2,max(s1,solve(u<<1|1,mid+1,r,mid+1,R)));}
}
char opt[10];
int main(){rd(n);rd(q);for(int i=1;i<=n;i++) rd(A[i]);for(int i=1;i<=n;i++) rd(B[i]);build(1,1,n);int l,r,d;while(q--){char c=getc();while(c!='A'&&c!='B')c=getc();rd(l);rd(r);rd(d);if(c=='A')update(1,1,n,l,r,d,1);else update(1,1,n,l,r,d,0);rd(l);rd(r);pre(1,1,n,l,r);PT(solve(1,1,n,l,r));putc('\n');} IO::flush();return 0;
}