题目大意
给定一个
1
到
解题思路
看到这题,感觉有点无从下手,好像怎么要都要枚举两个值。
但是我们可以发现一个很神奇的性质如果对于一个位置
i
,它是子等差序列中的第二项,那么如果不存在长度为
程序
//YxuanwKeith
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
const int Mo = 1e9 + 7;
const int MAXN = 3e5 + 5;
struct Node {
LL Num;
int len;
Node (LL num, int Len) {Num = num, len = Len;}
Node (){}
} Tr[2][MAXN * 4];
int N;
LL Pow[MAXN];
Node Merge(Node L, Node R) {
Node New;
New.len = L.len + R.len;
New.Num = (1ll * L.Num * Pow[R.len] + R.Num) % Mo;
return New;
}
void Build(int Ord, int Now, int l, int r) {
Tr[Ord][Now].len = r - l + 1;
if (l == r) return;
int Mid = (l + r) >> 1;
Build(Ord, Now * 2, l, Mid), Build(Ord, Now * 2 + 1, Mid + 1, r);
}
void Modify(int Ord, int Now, int l, int r, int Side) {
if (l == r) {
Tr[Ord][Now].Num = 1;
return;
}
int Mid = (l + r) >> 1;
if (Side <= Mid) Modify(Ord, Now * 2, l, Mid, Side); else
Modify(Ord, Now * 2 + 1, Mid + 1, r, Side);
if (!Ord) Tr[Ord][Now] = Merge(Tr[Ord][Now * 2], Tr[Ord][Now * 2 + 1]); else
Tr[Ord][Now] = Merge(Tr[Ord][Now * 2 + 1], Tr[Ord][Now * 2]);
}
Node Query(int Ord, int Now, int l, int r, int lx, int rx) {
if (lx > rx) return Node(0, 0);
if (l == lx && r == rx) return Tr[Ord][Now];
int Mid = (l + r) >> 1;
if (rx <= Mid) return Query(Ord, Now * 2, l, Mid, lx, rx); else
if (lx > Mid) return Query(Ord, Now * 2 + 1, Mid + 1, r, lx, rx); else {
Node L = Query(Ord, Now * 2, l, Mid, lx, Mid);
Node R = Query(Ord, Now * 2 + 1, Mid + 1, r, Mid + 1, rx);
if (!Ord) return Merge(L, R); else
return Merge(R, L);
}
}
int main() {
freopen("data.in", "r", stdin), freopen("data.out", "w", stdout);
scanf("%d", &N);
Pow[0] = 1;
Build(0, 1, 1, N), Build(1, 1, 1, N);
for (int i = 1; i <= N; i ++) Pow[i] = 1ll * Pow[i - 1] * 2 % Mo;
for (int i = 1; i <= N; i ++) {
int Now;
scanf("%d", &Now);
int len = min(Now - 1, N - Now);
if (Query(0, 1, 1, N, Now - len, Now - 1).Num != Query(1, 1, 1, N, Now + 1, Now + len).Num) {
printf("YES\n");
return 0;
}
Modify(0, 1, 1, N, Now);
Modify(1, 1, 1, N, Now);
}
printf("NO\n");
}