Description
You are given a permutation of numbers from 1 to n. Determine whether there’s a pair of integers a, b (1 ≤ a, b ≤ n; a ≠ b) such that the element (note, that it is usual division, not integer one) is between a and b in this permutation.
题解
加入了一个
a[i]
,怎样才会出现等差数列?显然,如果出现了等差数列,一定存在这样的一个
k
,使得
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 300006
#define tt 998244353
#define LL long long
using namespace std;
inline char nc(){
static char buf[100000],*i=buf,*j=buf;
return i==j&&(j=(i=buf)+fread(buf,1,100000,stdin),i==j)?EOF:*i++;
}
inline int _read(){
char ch=nc();int sum=0;
while(!(ch>='0'&&ch<='9'))ch=nc();
while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
return sum;
}
struct data{
int x,l,r;
LL suml,sumr;
}tree[maxn*4];
int n,a[maxn],P[maxn];
void build(int p,int l,int r){
tree[p].l=l;tree[p].r=r;
if(l>=r)return;
int mid=(l+r)>>1;
build(p<<1,l,mid);build(p<<1|1,mid+1,r);
}
void update(int p,int x){
if(x<tree[p].l||x>tree[p].r)return;
if(tree[p].l==tree[p].r){
tree[p].x=1;tree[p].suml=tree[p].sumr=1;
return;
}
update(p<<1,x);update(p<<1|1,x);
tree[p].suml=(tree[p<<1].suml*P[tree[p<<1|1].r-tree[p<<1|1].l+1]%tt+tree[p<<1|1].suml)%tt;
tree[p].sumr=(tree[p<<1|1].sumr*P[tree[p<<1].r-tree[p<<1].l+1]%tt+tree[p<<1].sumr)%tt;
}
LL queryl(int p,int l,int r){
if(l>tree[p].r||r<tree[p].l)return 0;
if(l<=tree[p].l&&r>=tree[p].r)return tree[p].suml%tt;
if(tree[p<<1].r>=l&&tree[p<<1|1].l<=r)return (queryl(p<<1,l,tree[p<<1].r)*P[r-tree[p<<1|1].l+1]%tt+queryl(p<<1|1,tree[p<<1|1].l,r))%tt;else
if(tree[p<<1].r>=r)return queryl(p<<1,l,r);else
return queryl(p<<1|1,l,r);
}
LL queryr(int p,int l,int r){
if(l>tree[p].r||r<tree[p].l)return 0;
if(l<=tree[p].l&&r>=tree[p].r)return tree[p].sumr%tt;
if(tree[p<<1].r>=l&&tree[p<<1|1].l<=r)return (queryr(p<<1|1,tree[p<<1|1].l,r)*P[tree[p<<1].r-l+1]%tt+queryr(p<<1,l,tree[p<<1].r))%tt;else
if(tree[p<<1].r>=r)return queryr(p<<1,l,r)%tt;else
return queryr(p<<1|1,l,r)%tt;
}
int main(){
n=_read();
build(1,1,n);
P[0]=1;
for(int i=1;i<=n;i++)P[i]=P[i-1]*2%tt;
for(int i=1;i<=n;i++){
a[i]=_read();
int l=max(1,2*a[i]-n),r=min(n,a[i]*2-1);
if((a[i]!=1)&&(a[i]!=n)&&((queryl(1,l,a[i]-1)^queryr(1,a[i]+1,r))!=0))return (printf("YES\n"),0);
update(1,a[i]);
}
printf("NO\n");
return 0;
}