QOJ.ac
QOJ
ID | 提交记录ID | 题目 | Hacker | Owner | 结果 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|
#1440 | #851489 | #9865. Dolls | GotoHiotori | GotoHiotori | Failed. | 2025-01-10 19:27:08 | 2025-01-10 19:27:08 |
詳細信息
Extra Test:
Accepted
time: 0ms
memory: 28552kb
input:
1 5 2 3 1 5 4
output:
4
result:
ok 1 number(s): "4"
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#851489 | #9865. Dolls | GotoHiotori | AC ✓ | 24ms | 141928kb | C++14 | 2.4kb | 2025-01-10 19:25:31 | 2025-01-10 19:25:33 |
answer
#include<bits/stdc++.h>
using namespace std;
namespace soyo{
int st_max[20][1000001],st_min[20][1000001],lg[1000001];
int Max(int l,int r){int k=lg[r-l+1];return max(st_max[k][l],st_max[k][r-(1<<k)+1]);}
int Min(int l,int r){int k=lg[r-l+1];return min(st_min[k][l],st_min[k][r-(1<<k)+1]);}
int stk[1000001],top;
int suf1[1000001],suf2[1000001];
int a[1000001];
int f[20][1000001];
void main(){
//freopen("doll.in","r",stdin),freopen("doll.out","w",stdout);
int n,q=1;
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%d",a+i),st_max[0][i]=st_min[0][i]=a[i];
int top=0;
for(int i=n;i>=1;--i){
for(;top&&a[stk[top-1]]<a[i];--top);
suf1[i]=top?stk[top-1]:n+1;
stk[top++]=i;
}
top=0;
for(int i=n;i>=1;--i){
for(;top&&a[stk[top-1]]>a[i];--top);
suf2[i]=top?stk[top-1]:n+1;
stk[top++]=i;
}
for(int i=2;i<=n;++i)lg[i]=lg[i>>1]+1;
for(int i=1;i<=lg[n];++i)
for(int j=1;j+(1<<i-1)<=n;++j)
st_max[i][j]=max(st_max[i-1][j],st_max[i-1][j+(1<<i-1)]),
st_min[i][j]=min(st_min[i-1][j],st_min[i-1][j+(1<<i-1)]);
f[0][n]=n+1;
for(int i=n-1;i>=1;--i)
if(a[i+1]<a[i]){
if(suf1[i]<f[0][i+1]){
int l=suf1[i],r=f[0][i+1];
for(;l<r;){
int mid=l+r>>1;
if(Min(suf1[i],mid)>a[i])l=mid+1;
else r=mid;
}
if(l<f[0][i+1]&&a[l]<Min(i,l-1))f[0][i]=f[0][i+1];
else f[0][i]=l;
}else f[0][i]=f[0][i+1];
}else{
if(suf2[i]<f[0][i+1]){
int l=suf2[i],r=f[0][i+1];
for(;l<r;){
int mid=l+r>>1;
if(Max(suf2[i],mid)<a[i])l=mid+1;
else r=mid;
}
if(l<f[0][i+1]&&a[l]>Max(i,l-1))f[0][i]=f[0][i+1];
else f[0][i]=l;
}else f[0][i]=f[0][i+1];
}
for(int i=1;i<=lg[n];++i)
for(int j=1;j<=n;++j)
if(f[i-1][j]>n)f[i][j]=n+1;
else f[i][j]=f[i-1][f[i-1][j]];
for(int l=1,r=n;q--;){
int res=r-l;
for(int i=lg[n];i--;)
if(f[i][l]<=r)
l=f[i][l],res-=(1<<i);
printf("%d\n",res);
}
}
}
int main(){
int t;
for(scanf("%d",&t);t--;)
soyo::main();
return 0;
}