挺厉害的题
我们考虑当前加入了第i个数,为x,那么我们可以维护一下哪个数出现过,出现过为1,没出现为0,那么加入x的时候我们只需要判断以x为中心的极长子串是否是回文串即可
用一个树状数组维护两个方向的哈希值即可
#include<iostream>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<cstdlib>
#include<cstdio>
#include<map>
#include<bitset>
#include<set>
#include<stack>
#include<vector>
#include<queue>
using namespace std;
#define MAXN 10010
#define MAXM 1010
#define ll long long
#define eps 1e-8
#define MOD 1000000007
#define INF 1000000000
#define lb(x) x&-x
int n;
int x;
ll c1[MAXN],c2[MAXN];
ll bas=131;
ll mi[MAXN];
void change(ll *c,int x,ll cv){
for(;x<=n;x+=lb(x)){
(c[x]+=cv)%=MOD;
}
}
ll ask(ll *c,int x){
ll re=0;
for(;x;x-=lb(x)){
(re+=c[x])%=MOD;
}
return re;
}
int main(){
int i;
int tmp;
scanf("%d",&tmp);
mi[0]=1;
for(i=1;i<MAXN;i++){
mi[i]=mi[i-1]*bas%MOD;
}
while(tmp--){
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
bool flag=0;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d",&x);
change(c1,x,mi[x]);
change(c2,n-x+1,mi[n-x+1]);
int len1=x,len2=n-x+1;
if(len1<=len2){
ll h1=ask(c1,len1)*mi[len2-len1]%MOD;
ll h2=(ask(c2,len2)-ask(c2,len2-len1)+MOD)%MOD;
if(h1!=h2){
flag=1;
}
}else{
ll h1=(ask(c1,len1)-ask(c1,len1-len2)+MOD)%MOD;
ll h2=ask(c2,len2)*mi[len1-len2]%MOD;
if(h1!=h2){
flag=1;
}
}
}
printf(flag?"Y\n":"N\n");
}
return 0;
}
/*
*/