[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
3
1 3 2
3
3 2 1
Sample Output
N
Y
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; }