[JRKSJ R1] JFCA
题目描述
给出一个环,上面有 n 个点,每个相邻的点对之间的距离为 $1$。
每个点有两个属性 a_i 和 b_i,对于点 i,定义 f_i 为它与满足 a_j\ge b_i 的最近的点 j 与 i 在环上距离较短一边的长度,其中 i\ne j。如果没有满足条件的 j,其 f_i=-1。
输入格式
输入共 3 行.
第 1 行 1 个整数 n 。
第 2 行 n 个整数,其中第 i 个表示 a_i,意义同上。
第 3 行 n 个整数,其中第 i 个表示 b_i,意义同上。
输出格式
输出 1 行 n 个整数,其中第 i 个表示 f_i,意义同上。
样例 #1
样例输入 #1
3
1 2 3
3 2 1
样例输出 #1
1 1 1
样例 #2
样例输入 #2
5
5 4 3 5 6
7 6 5 4 3
样例输出 #2
-1 2 1 1 1
样例 #3
样例输入 #3
5
1 1 2 1 1
2 2 2 2 2
样例输出 #3
2 1 -1 1 2
提示
对于 20% 的数据,1<=n<= 10^3;
对于 100% 的数据,1<=n<= 10^5,1<=a_i,b_i<= 10^9。
我们对于测试点 4 至 11 采用捆绑测试。
样例 1 解释
对于 i=1,a_3=3= b_1=3, 1 和3 的距离是 1,所以 f_1=1。
对于 i=2,a_3=3> b_2=2, 2 和3 的距离是 1,所以 f_2=1。
对于 i=3,a_2=2> b_3=1, 2 和3 的距离是 1,所以 f_3=1。
我那时自信提交(别复制太早,还有下面)
#include<bits/stdc++.h>
using namespace std;
int n,a[20][300005],b[100005],len;
int f(int x,int y){
int len=log2(y-x+1);
return max(a[len][x],a[len][y-(1<<len)+1]);
}
int mf(int x,int p){
for(int i=1;i<n;i++){
if(max(f(p-i,p-1),f(p+1,p+i))>=x)return i;
}
return -1;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[0][i];
a[0][i+n]=a[0][i+2*n]=a[0][i];
}
for(int i=1;i<=n;i++){
cin>>b[i];
}
len=log2(n);
for(int i=1;i<=len;i++){
for(int j=1;j<=3*n-(1<<i)+1;j++){
a[i][j]=max(a[i-1][j],a[i-1][j+(1<<i-1)]);
}
}
for(int i=1;i<=n;i++){
cout<<mf(b[i],i+n)<<" ";
}
return 0;
}
结果只有20分
哇,全是TLE(超时)
后来我找了好久错误
才发现这里
int mf(int x,int p){
for(int i=1;i<n;i++){
if(max(f(p-i,p-1),f(p+1,p+i))>=x)return i;
}
return -1;
}
原来这里算引用了3个循环
难怪会TLE
然后我采用了二分
int mf(int x,int p){
int l=1,r=n,mid;
while(l<r){
mid=l+r>>1;
if(max(f(p-mid,p-1),f(p+1,p+mid))>=x)r=mid;
else l=mid+1;
}
if(l<n)return l;
return -1;
}
自行提交
代码:
#include<bits/stdc++.h>//已AC
using namespace std;
int n,a[20][300005],b[100005],len;
int f(int x,int y){
int len=log2(y-x+1);
return max(a[len][x],a[len][y-(1<<len)+1]);
}
int mf(int x,int p){
int l=1,r=n,mid;
while(l<r){
mid=l+r>>1;
if(max(f(p-mid,p-1),f(p+1,p+mid))>=x)r=mid;//二分
else l=mid+1;
}
if(l<n)return l;
return -1;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[0][i];
a[0][i+n]=a[0][i+2*n]=a[0][i];
}
for(int i=1;i<=n;i++){
cin>>b[i];
}
len=log2(n);
for(int i=1;i<=len;i++){
for(int j=1;j<=3*n-(1<<i)+1;j++){
a[i][j]=max(a[i-1][j],a[i-1][j+(1<<i-1)]);
}
}
for(int i=1;i<=n;i++){
cout<<mf(b[i],i+n)<<" ";
}
return 0;
}
拜拜