版权声明:写得不好,转载请通知一声,还请注明出处,感激不尽 https://blog.csdn.net/As_A_Kid/article/details/83652093
Problem
给你一个长度为 的排列,问你存不存在 使得 。
Solution
一道很有意思的题目。。我做的时候思路从fft到线段树再到bitset到分治再到构造,反正就是搞来搞去不可做。。
我们考虑枚举 ,如果存在 满足要求的话,就说明存在一个 ,使得 与 在前j个位置中的存在状态不同,如果完全一致就说明不存在。把存在状态表示成一个01串,就相当于询问串 和串 是不是对称的,那翻转其中一个串再匹配。那么算法的瓶颈就在于如何快速的判断两个01串相同,用权值线段树维护hash值。
时间复杂度
Code
#include <algorithm>
#include <cstdio>
#define rg register
#define pushup(rt) a[rt]=a[rt<<1]+a[rt<<1|1],b[rt]=b[rt<<1|1]+b[rt<<1]
using namespace std;
typedef long long ll;
const int maxn=300010,base=7,mod=998244353;
template <typename Tp> inline int getmin(Tp &x,Tp y){return y<x?x=y,1:0;}
template <typename Tp> inline int getmax(Tp &x,Tp y){return y>x?x=y,1:0;}
template <typename Tp> inline void read(Tp &x)
{
x=0;int f=0;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
if(f) x=-x;
}
int n,x,p,pw[maxn];
inline int pls(int x,int y){return x+y>=mod?x+y-mod:x+y;}
struct data{
int val,len;
data (const int _val=0,const int _len=0){val=_val;len=_len;}
data operator + (const data &b)const
{
return data(pls(((ll)val*pw[b.len]%mod),b.val),len+b.len);
}
}ta,tb,a[maxn<<2],b[maxn<<2];
void build(int l,int r,int rt)
{
if(l==r)
{
a[rt]=b[rt]=data(0,1);
return ;
}
int m=(l+r)>>1;
build(l,m,rt<<1);build(m+1,r,rt<<1|1);
pushup(rt);
}
void update(int l,int r,int pos,int rt)//insert
{
if(l==r){a[rt]=b[rt]=data(1,1);return ;}
int m=(l+r)>>1;
if(pos<=m) update(l,m,pos,rt<<1);
else update(m+1,r,pos,rt<<1|1);
pushup(rt);
}
data qa(int l,int r,int L,int R,int rt)
{
if(L<=l&&r<=R) return a[rt];
int m=(l+r)>>1;data res;
if(L<=m) res=res+qa(l,m,L,R,rt<<1);
if(m<R) res=res+qa(m+1,r,L,R,rt<<1|1);
return res;
}
data qb(int l,int r,int L,int R,int rt)
{
if(L<=l&&r<=R) return b[rt];
int m=(l+r)>>1;data res;
if(m<R) res=res+qb(m+1,r,L,R,rt<<1|1);
if(L<=m) res=res+qb(l,m,L,R,rt<<1);
return res;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
read(n);
pw[0]=1;
for(rg int i=1;i<=n;i++) pw[i]=(ll)pw[i-1]*base%mod;
build(1,n,1);
for(rg int i=1;i<=n;i++)
{
read(x);
update(1,n,x,1);
p=min(x-1,n-x);
if(p<=0) continue;
ta=qa(1,n,x-p,x-1,1);
tb=qb(1,n,x+1,x+p,1);
if(ta.val!=tb.val){puts("YES");return 0;}
}
puts("NO");
return 0;
}