P14378 【MX-S9-T1】「LAOI-16」签到题解
P14378 【MX-S9-T1】「LAOI-16」签到
好想不好写!
简单贪心思路就是,小的数尽可能对应大的数,这样序列一个从小到大,一个从大到小。
一个数修改,只会使他当前位置到新到达的位置中间的数挪动,区间以外的其他数不动,区间内的数相当于整体平移对应,然后建线段树求平移后区间最大值最小值,\(a[i+1]+b[i]\) 和 \(a[i-1]+b[i]\)。
注意二分部分,这点很重要,要动脑子仔细思考为什么这么二分区间。
#include<bits/stdc++.h>
#define ll long long
//#define int ll
#define ls p<<1
#define rs p<<1|1
#define re register
#define pb push_back
#define pir pair<int,int>
#define f(a,x,i) for(int i=a;i<=x;i++)
#define fr(a,x,i) for(int i=a;i>=x;i--)
#define lowbit(x) (x&-x)
using namespace std;
const int N=1e7+10;
const int M=5e6+10;
const int mod=1e9+7;
const int INF=1e9+7;
mt19937 rnd(251);
int n,k,q;
int a[N];
int b[N];
int c[N];
int cnt=0;
int pre_max[N];
int pre_min[N];
int suf_max[N];
int suf_min[N];
int t1_max[N];//a[l+1]+b[l]
int t1_min[N];
int t2_max[N];//a[l-1]+b[l]
int t2_min[N];
bool cmp(int g,int h){
return g>h;
}
void build(int p,int l,int r){
if(l==r){
t1_max[p]=a[l+1]+b[l];
t1_min[p]=a[l+1]+b[l];
t2_max[p]=a[l-1]+b[l];
t2_min[p]=a[l-1]+b[l];
return;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
t1_max[p]=max(t1_max[ls],t1_max[rs]);
t1_min[p]=min(t1_min[ls],t1_min[rs]);
t2_max[p]=max(t2_max[ls],t2_max[rs]);
t2_min[p]=min(t2_min[ls],t2_min[rs]);
}
int query_max1(int p,int pl,int pr,int l,int r){
if(l<=pl&&pr<=r){
return t1_max[p];
}
int mid=(pl+pr)>>1;
int ans=0;
if(l<=mid){
ans=max(ans,query_max1(ls,pl,mid,l,r));
}
if(r>mid){
ans=max(ans,query_max1(rs,mid+1,pr,l,r));
}
return ans;
}
int query_max2(int p,int pl,int pr,int l,int r){
if(l<=pl&&pr<=r){
return t2_max[p];
}
int mid=(pl+pr)>>1;
int ans=0;
if(l<=mid){
ans=max(ans,query_max2(ls,pl,mid,l,r));
}
if(r>mid){
ans=max(ans,query_max2(rs,mid+1,pr,l,r));
}
return ans;
}
int query_min1(int p,int pl,int pr,int l,int r){
if(l<=pl&&pr<=r){
return t1_min[p];
}
int mid=(pl+pr)>>1;
int ans=INF;
if(l<=mid){
ans=min(ans,query_min1(ls,pl,mid,l,r));
}
if(r>mid){
ans=min(ans,query_min1(rs,mid+1,pr,l,r));
}
return ans;
}
int query_min2(int p,int pl,int pr,int l,int r){
if(l<=pl&&pr<=r){
return t2_min[p];
}
int mid=(pl+pr)>>1;
int ans=INF;
if(l<=mid){
ans=min(ans,query_min2(ls,pl,mid,l,r));
}
if(r>mid){
ans=min(ans,query_min2(rs,mid+1,pr,l,r));
}
return ans;
}
void solve(){
cin>>n>>k>>q;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=k;i++){
cin>>c[i];
}
for(int i=1;i<=k;i++){
int x;
cin>>x;
for(int j=1;j<=c[i];j++){
b[++cnt]=x;
}
}
for(int i=1;i<=n;i++){
c[i]=a[i];
}
sort(a+1,a+1+n);
sort(b+1,b+1+n,cmp);
//前缀
pre_min[0]=INF;
for(int i=1;i<=n;i++){
pre_max[i]=max(pre_max[i-1],a[i]+b[i]);
pre_min[i]=min(pre_min[i-1],a[i]+b[i]);
}
//后缀
suf_min[n+1]=INF;
for(int i=n;i>=1;i--){
suf_max[i]=max(suf_max[i+1],a[i]+b[i]);
suf_min[i]=min(suf_min[i+1],a[i]+b[i]);
}
build(1,1,n);
for(int i=1;i<=q;i++){
int x,y;
cin>>x>>y;
k=c[x];
if(k==y){
cout<<pre_max[n]-pre_min[n]<<"\n";
continue;
}
int l,r;
int mx=0,mi=INF;
if(k<=y){
l=upper_bound(a+1,a+1+n,k)-a-1;
r=lower_bound(a+1,a+1+n,y)-a-1;
l=max(l,1);
r=min(r,n);
mx=max(mx,query_max1(1,1,n,l,r-1));
mx=max(mx,y+b[r]);
mi=min(mi,query_min1(1,1,n,l,r-1));
mi=min(mi,y+b[r]);
}
else{
l=upper_bound(a+1,a+1+n,y)-a;
r=lower_bound(a+1,a+1+n,k)-a;
l=max(l,1);
r=min(r,n);
mx=max(mx,query_max2(1,1,n,l+1,r));
mx=max(mx,y+b[l]);
mi=min(mi,query_min2(1,1,n,l+1,r));
mi=min(mi,y+b[l]);
}
mx=max(mx,pre_max[l-1]);
mx=max(mx,suf_max[r+1]);
mi=min(mi,pre_min[l-1]);
mi=min(mi,suf_min[r+1]);
// cout<<l<<" "<<r<<"\n";
// cout<<"ans=";
cout<<mx-mi<<"\n";
}
}
signed main(){
// freopen("replace4.in","r",stdin);
// freopen("a.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(nullptr);
solve();
return 0;
}

浙公网安备 33010602011771号