题解 P7333 [JRKSJ R1] JFCA
一道不难的题目。
题意已经很明确了。我们发现数据范围是
题解
我们要找到与
为了优化复杂度,我们维护一个区间内
但因为这是一个环,为了断环成链,需要开三倍空间,方便处理左右边界,并将原来的
容易想到分块。
对于
时间复杂度为
您也可以像出题人那样写二分 ST 表,思路都很简单。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n , a[N * 3] , b[N * 3] , belong[N * 3] , f[N];
int L , C , s[N * 3] , t[N * 3] , maxx[N * 3];
void init() {
C = 0;
L = sqrt(3 * n);
for(int i = 1; i <= n * 3; i += L) {
s[++ C] = i;
t[C] = min(n * 3 , i + L - 1);
for(int j = s[C]; j <= t[C]; j ++) {
belong[j] = C;
maxx[C] = max(maxx[C] , a[j]);
}
}
}
int query_l(int x , int k) {
int edge = belong[x];
for(int i = x - 1; i >= s[edge]; i --)
if(a[i] >= k)
return x - i;
for(int i = edge - 1; i >= 1; i --)
if(maxx[i] >= k)
for(int j = t[i]; j >= s[i]; j --)
if(a[j] >= k)
return x - j;
return -1;
}
int query_r(int x , int k) {
int edge = belong[x];
for(int i = x + 1; i <= t[edge]; i ++)
if(a[i] >= k)
return i - x;
for(int i = edge + 1; i <= C; i ++)
if(maxx[i] >= k)
for(int j = s[i]; j <= t[i]; j ++)
if(a[j] >= k)
return j - x;
return -1;
}
int main() {
scanf("%d" , &n);
for(int i = 1; i <= n; i ++)
scanf("%d" , &a[i]) , a[i + n] = a[i] , a[i + n + n] = a[i];
for(int i = 1; i <= n; i ++)
scanf("%d" , &b[i]);
init();
for(int i = 1; i <= n; i ++) {
f[i] = min(query_l(n + i , b[i]) , query_r(n + i , b[i]));
if(f[i] == n)
f[i] = -1;
}
for(int i = 1; i <= n; i ++)
printf("%d " , f[i]);
return 0;
}
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!