1. 程式人生 > >BZOJ2124: 等差子序列(樹狀數組&hash -> bitset 求是否存在長度為3的等差數列)

BZOJ2124: 等差子序列(樹狀數組&hash -> bitset 求是否存在長度為3的等差數列)

hash EDA str class 直觀 content 一個 方向 bmi

2124: 等差子序列

Time Limit: 3 Sec Memory Limit: 259 MB
Submit: 2354 Solved: 826
[Submit][Status][Discuss]

Description

給一個1到N的排列{Ai},詢問是否存在1<=p1<p2<p3<p4<p5<…<pLen<=N (Len>=3), 使得Ap1,Ap2,Ap3,…ApLen是一個等差序列。

Input

輸入的第一行包含一個整數T,表示組數。 下接T組數據,每組第一行一個整數N,每組第二行為一個1到N的排列,數字兩兩之間用空格隔開。 N<=10000,T<=7

Output

對於每組數據,如果存在一個等差子序列,則輸出一行“Y”,否則輸出一行“N”。

Sample Input

2
3
1 3 2
3
3 2 1

Sample Output

N
Y

HINT

Source

思路:題目即是問有沒有等於3的等差數列。 最直觀的解決就是從前往後掃,假設掃到X了,我們去看關於X對稱的數,是否其出現的情況不相同,vis[X+i]!=vis[X-i]。

我們可以用兩個hash來維護兩個方向的01字符串,表示出現情況。這裏野可以用bitset來解決。

#include<bits/stdc++.h>
using
namespace std; const int maxn=20010; int a[maxn],N; bool check() { bitset<maxn>s,t; for(int i=1;i<=N;i++) t[i]=1; for(int i=1;i<=N;i++){ t[a[i]]=0; if(((s>>(20001-a[i]*2))&t).any()) return true; s[20001-a[i]]=1; } return false; }
int main() { int T; scanf("%d",&T); while(T--){ scanf("%d",&N); for(int i=1;i<=N;i++) scanf("%d",&a[i]); if(check()) puts("Y"); else puts("N"); } return 0; }

BZOJ2124: 等差子序列(樹狀數組&hash -> bitset 求是否存在長度為3的等差數列)