[BZOJ2124]等差子序列

2124: 等差子序列

Time Limit: 3 Sec  Memory Limit: 259 MB Submit: 1504  Solved: 548 [Submit][Status][Discuss]

Description

给一个1到N的排列{Ai},询问是否存在1<=p1=3),使得Ap1,Ap2,Ap3,…ApLen是一个等差序列。

Input

输入的第一行包含一个整数T,表示组数。下接T组数据,每组第一行一个整数N,每组第二行为一个1到N的排列,数字两两之间用空格隔开。

Output

对于每组数据,如果存在一个等差子序列,则输出一行“Y”,否则输出一行“N”。

Sample Input

2
3
1 3 2
3
3 2 1

Sample Output

N
Y

HINT

对于100%的数据,N<=10000,T<=7

 

考虑插入并枚举每个数为等差中项,如果序列不存在等差数列,那么在它前面所有出现的数中,任意一个可能存在对应数的数都能找到对应的数,否则对应的数一定会出现在后面(因为是$1$到$n$的排列),所以可以考虑维护一个权值线段树,如果一个数出现过就标记为1,然后支持查询区间哈希值(正反)就行了

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
char buf[10000000], *ptr = buf - 1;
inline int readint(){
    int n = 0;
    char ch = *++ptr;
    while(ch < '0' || ch > '9') ch = *++ptr;
    while(ch <= '9' && ch >= '0'){
        n = (n << 1) + (n << 3) + ch - '0';
        ch = *++ptr;
    }
    return n;
}
typedef unsigned long long ull;
const int maxn = 10000 + 10;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
ull h1[maxn << 2], h2[maxn << 2], pow[maxn];
void Update(int w, int l, int r, int rt){
    if(l == r) h1[rt] = h2[rt] = 1;
    else{
        int mid = l + r >> 1;
        if(w <= mid) Update(w, lson);
        else Update(w, rson);
        h1[rt] = h1[rt << 1] * pow[r - mid] + h1[rt << 1 | 1];
        h2[rt] = h2[rt << 1 | 1] * pow[mid - l + 1] + h2[rt << 1];
    }
}
ull Query1(int ql, int qr, int l, int r, int rt){
    if(ql <= l && r <= qr) return h1[rt];
    else{
        int mid = l + r >> 1;
        if(ql > mid) return Query1(ql, qr, rson);
        else if(qr <= mid) return Query1(ql, qr, lson);
        else return Query1(ql, qr, lson) * pow[min(qr, r) - mid] + Query1(ql, qr, rson);
    }
}
ull Query2(int ql, int qr, int l, int r, int rt){
    if(ql <= l && r <= qr) return h2[rt];
    else{
        int mid = l + r >> 1;
        if(ql > mid) return Query2(ql, qr, rson);
        else if(qr <= mid) return Query2(ql, qr, lson);
        else return Query2(ql, qr, lson) + Query2(ql, qr, rson) * pow[mid - max(ql, l) + 1];
    }
}
int main(){
    fread(buf, sizeof(char), sizeof(buf), stdin);
    pow[0] = 1;
    for(int i = 1; i <= 10000; i++) pow[i] = pow[i - 1] * 6662333;
    int T = readint(), n;
    while(T--){
        n = readint();
        memset(h1, 0, sizeof h1);
        memset(h2, 0, sizeof h2);
        bool flag = false;
        for(int t, len, i = 1; i <= n; i++){
            t = readint();
            len = min(t - 1, n - t);
            if(!flag && len && Query1(t - len, t - 1, 1, n, 1) != Query2(t + 1, t + len, 1, n, 1)) flag = true;
            Update(t, 1, n, 1);
        }
        puts(flag ? "Y" : "N");
    }
    return 0;
}

 

posted @ 2017-09-11 17:48  Elder_Giang  阅读(207)  评论(0编辑  收藏  举报