题意:
给出两个长度为N的数组A,B,以及一种计算规律:
若t[i]=1,需满足t[i-1]=t[i-2]=t[i-3]=t[i-4]=0,以及max{A[i],A[i-1],A[i-2],A[i-3],A[i-4]} < l
若t[i]=0,需满足t[i-1]=t[i-2]=t[i-3]=t[i-4]=1,以及min{A[i],A[i-1],A[i-2],A[i-3],A[i-4]} > r
其他情况:t[i]=t[i-1]
(|l|,|r|≤109)
(
|
l
|
,
|
r
|
≤
10
9
)
现在要使得运算一次的结果t=B,求满足条件的l,r(保证有解)
N≤100000
分析:
非常简单地O(n)枚举一次,维护l与r的取值范围即可
首先,如果目标串中:
1、
Bi=Bi−1=1
B
i
=
B
i
−
1
=
1
,那么如果前4位均为1,则必须使
t[i]=0
t
[
i
]
=
0
的条件不满足,即
rmax < min{A[i],A[i-1],A[i-2],A[i-3],A[i-4]}
如果前4位不均为1,则不需要改变
2、 Bi=Bi−1=0 B i = B i − 1 = 0 ,和上面是一样的,稍微对应地修改一下即可
3、
Bi=1≠Bi−1
B
i
=
1
≠
B
i
−
1
,因为题目保证有解,所以前4位必然为0,所以要满足:
lmin > max{A[i],A[i-1],A[i-2],A[i-3],A[i-4]}
4、
Bi=0≠Bi−1
B
i
=
0
≠
B
i
−
1
,也和上面是一样的,稍加修改即可
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 100010
#define INF 1000000000
using namespace std;
int n;
int a[MAXN];
char b[MAXN];
int minl=-INF,maxl=INF,minr=-INF,maxr=INF;
int check(int x){
int res=-2;
for(int i=x-1;i>=x-4;i--){
if(res==-2){
res=b[i];
}
else if(b[i]!=res)
res=-1;
}
return res;
}
int find_min(int x){
int res=a[x];
for(int i=x-1;i>=x-4;i--)
res=min(res,a[i]);
return res;
}
int find_max(int x){
int res=a[x];
for(int i=x-1;i>=x-4;i--)
res=max(res,a[i]);
return res;
}
int main(){
SF("%d",&n);
for(int i=0;i<n;i++)
SF("%d",&a[i]);
SF("%s",b);
for(int i=0;i<n;i++)
b[i]-='0';
for(int i=4;i<n;i++){
if(b[i]==b[i-1]){
if(check(i)==1&&b[i]==1){
minr=max(minr,find_min(i));
}
if(check(i)==0&&b[i]==0){
maxl=min(maxl,find_max(i));
}
}
else{
if(b[i]==1){
minl=max(minl,find_max(i)+1);
}
else{
maxr=min(maxr,find_min(i)-1);
}
}
}
PF("%d %d\n",minl,maxr);
}