题目链接
第一次学到手写的双向队列,利用懒标记维护区间的翻转,改变不同的修改方式,从而达到相同的效果,复杂度o(n),真是太牛辣!
#include<bits/stdc++.h>
using namespace std;
const int MAXN=100005;
int a[MAXN],pos[MAXN],k,n;
bool flag=true;
struct deQue
{
int buffer[MAXN*2];
int head=MAXN,tail=MAXN-1;
bool rev;
bool empty()
{
return tail<head;
}
int size()
{
return tail-head+1;
}
int front()
{
return rev?buffer[tail]:buffer[head];
}
int back()
{
return rev?buffer[head]:buffer[tail];
}
void push_front(int x)
{
rev?buffer[++tail]=x:buffer[--head]=x;
}
void push_back(int x)
{
rev?buffer[--head]=x:buffer[++tail]=x;
}
void pop_back()
{
rev?head++:tail--;
}
void pop_front()
{
rev?tail--:head++;
}
void reverse()
{
rev^=1;
}
}q;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%d",&a[i]);
pos[a[i]]=i;
}
bool isOK=true;
for(int i=1;i<=n;++i)
{
if(a[i]!=i)
{
k=pos[i]-i+1;
isOK=false;
break;
}
}
if(isOK)
{
printf("yes\n1\n");
return 0;
}
for(int i=1;i<=k;++i)
{
q.push_back(a[i]);
}
for(int i=1;i<=n;++i)
{
if(q.front()!=i&&q.size()==k)q.reverse();
if(q.front()!=i)
{
flag=false;
break;
}
q.pop_front();
if(i+k<=n)
{
q.push_back(a[i+k]);
}
}
if(flag)
{
printf("yes\n%d\n",k);
}
else
{
printf("no\n");
}
return 0;
}