\(GZOI2017D2T2\)
题目链接?不存在的
首先,题目可以转化为是否存在长度为\(3\)的等差子序列。
枚举中间的那个数\(a_i\),判断两边是否存在两个数和中间这个数组成等差数列。
枚举差值\(d\),判断是否存在\(a_i-d,a_i+d\),这一步可以bitset加速。
但是还是比较慢,数据挺水,不知道能不能卡TLE。。
时间复杂度 \(O(T\frac{n^2}{32})\)
代码:
#include <cstdio>
#include <bitset>
#include <cstring>
#include <algorithm>
#define Sub(B,l,r) (B>>(l)&One[(r)-(l)])
const int N=20005;
int T,n,a[N],c[N];
std::bitset<N> Pre,Suf,One[N];
int main()
{
One[0].set(0);
for(int i=1;i<=20000;++i)(One[i]=One[i-1]).set(i);
for(scanf("%d",&T);T--;)
{
scanf("%d",&n),Pre.reset(),Suf.reset(),memset(c,0,sizeof c);
for(int i=1;i<=n;++i)scanf("%d",&a[i]);
for(int i=1;i<=n;++i)++c[a[i]],Suf.set(a[i]);
bool Flag=false;
for(int i=1;i<=n;++i)
{
if(!--c[a[i]])Suf.reset(a[i]);
int l=std::min(a[i]-1,20000-a[i]);
if((Sub(Pre,20001-a[i]-l,20001-a[i]+l)&Sub(Suf,a[i]-l,a[i]+l)).count())Flag=true,i=n;
Pre.set(20001-a[i]);
}
puts(Flag?"YES":"NO");
}
return 0;
}