题目
题解思路
性质(突破点):由于翻转一次后只能翻转左端点之后的点,所以这个翻转的左端点必然要让它等于i,如果这样不能相等那么之后一定翻转不到它。
这样就形不成这个序列了。
那么如果模拟这个过程呢?
直接数组reverse?那肯定超时的。
大佬们提供了一种思路利用双端队列来两头判断数。
当这段区间翻转后从后头加数,前头先将翻转区间导入。
当相等就将前头的数pop
不等的时候肯定是需要翻转或者操作不到了。
再翻转后就前头加数,后头先将翻转区间导入。
以此类推。
表示好这两种状态即可。
当数加完的时候,要判断双端队列里的数是否递增或递减。
下附数组实现此题双端队列的功能。
双端队列卡常。
AC代码
const int MAXN=1e5+5;
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;
#include <bits/stdc++.h>
//#include <unordered_map>
//priority_queue
#define PII pair<int,int>
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 100010 ;
long long a[N] , b[N] ;
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int n ,pit = -1 ;
cin >> n ;
for (int i = 1 ; i <= n ; i++ )
cin >> a[i] ;
for (int i = 1 ; i <= n ; i++ )
{
if (a[i]!=i)
{
pit = i;
break ;
}
}
if (pit == -1 )
{
cout << "YES\n1\n";
}else
{
int falg = 1 ;
int k ;
for (int i = pit + 1 ; i <= n ; i++ )
{
if (a[i] == pit )
{
k = i ;
break ;
}
}
int sp = k - pit + 1 ;
int st = 1 ;
deque <int> q ;
for (int i = pit ; i <= k ; i++ )
{
q.push_front(a[i]);
}
for (int j = k + 1 ; j <= n ; j++ )
{
if (st)
{
if (q.front() == pit )
{
while (j <= n && q.front() == pit)
{
q.pop_front() ;
q.push_back(a[j]);
pit++;
j++;
}
j--;
}else
{
falg = 0 ;
break;
}
st = 0 ;
}else
{
if (q.back() == pit )
{
while (j <= n && q.back() == pit )
{
q.pop_back() ;
q.push_front(a[j]);
pit++;
j++;
}
j-- ;
}else
{
falg = 0 ;
break ;
}
st = 1 ;
}
}
if (falg)
{
int j=0;
for(deque<int>::iterator it=q.begin();it!=q.end();it++){
b[j++]=(*it);
}
if( b[0] == pit )
{
for(int i=0; i < j ; i++ )
{
if(b[i] != pit + i )
falg=0;
}
}
else{
for(int i=0;i<j;i++)
{
if(b[i] != n-i )
falg = 0;
}
}
}
if (falg)
cout << "yes\n" << sp << "\n" ;
else
cout << "no\n" ;
}
return 0 ;
}