BZOJ 2124: 等差子序列

只需要找到长度为 \(3\) 的等差子序列即可,可以枚举每一个位置,用bitset预处理出左边有什么值以及右边有哪些翻转的值,然后再与一下,复杂度是 \(O(\dfrac{n^2}{32})\),但是它T了
不需要求出具体公差是啥,那么我们看当前位置 \(i\) 的值 \(x\)\(1\)\(i-1\)\([1,x-1]\) 的值的出现情况与 \([x+1,n]\) 是否一致,不一致就肯定右边有对应的值能成为等差数列
用支持单点修改区间查询的数据结构维护哈希值即可

#include <bits/stdc++.h>
#define pb push_back
#define fi first
#define se second
#define pii pair<int, int>
#define lp p << 1
#define rp p << 1 | 1
#define mid ((l + r) >> 1)
#define ll long long
#define db double
#define rep(i,a,b) for(int i=a;i<b;i++)
#define per(i,a,b) for(int i=b-1;i>=a;i--)
#define Edg int ccnt=1,head[N],to[N*2],ne[N*2];void addd(int u,int v){to[++ccnt]=v;ne[ccnt]=head[u];head[u]=ccnt;}void add(int u,int v){addd(u,v);addd(v,u);}
#define Edgc int ccnt=1,head[N],to[N*2],ne[N*2],c[N*2];void addd(int u,int v,int w){to[++ccnt]=v;ne[ccnt]=head[u];c[ccnt]=w;head[u]=ccnt;}void add(int u,int v,int w){addd(u,v,w);addd(v,u,w);}
#define es(u,i,v) for(int i=head[u],v=to[i];i;i=ne[i],v=to[i])
const int MOD = 1e9 + 9;
void M(int &x) {if (x >= MOD)x -= MOD; if (x < 0)x += MOD;}
int qp(int a, int b = MOD - 2) {int ans = 1; for (; b; a = 1LL * a * a % MOD, b >>= 1)if (b & 1)ans = 1LL * ans * a % MOD; return ans % MOD;}
int gcd(int a, int b) { while (b) { a %= b; std::swap(a, b); } return a; }

const int N = 1e4 + 7;
int base[N], seed = 2, n;

struct Bit {
	int tree[N];
	inline void clear() { memset(tree, 0, sizeof(int) * (n + 2)); }
	inline int lowbit(int x) { return x & -x; }
	inline void add(int x) { for (int i = x; i <= n; i += lowbit(i)) M(tree[i] += base[i - x]); }
	inline int query(int x) { int ans = 0; for (int i = x; i; i -= lowbit(i)) M(ans += 1LL * tree[i] * base[x - i] % MOD); return ans; }
	inline int query(int l, int r) { return ((query(r) - 1LL * query(l - 1) * base[r - l + 1] % MOD + MOD) % MOD); }
} le, ri;

void solve() {
	scanf("%d", &n);
	le.clear(); ri.clear();
	bool ans = 0;
	rep (i, 1, n + 1) {
		int x;
		scanf("%d", &x);
		if (ans) continue;
		int point = std::min(x - 1, n - x);
		if (point && le.query(x - point, x - 1) != ri.query(n - x - point + 1, n - x)) ans = 1;
		le.add(x); ri.add(n - x + 1);
	}
	puts(ans ? "Y" : "N");
}

int main() {
	for (int i = base[0] = 1; i < N; i++)
		base[i] = 1LL * base[i - 1] * seed % MOD;
	int T;
	scanf("%d", &T);
	while (T--) solve();
}
posted @ 2020-02-23 20:30  Mrzdtz220  阅读(114)  评论(0编辑  收藏  举报