Rt,用的两个线段树,求大佬帮忙调一下,大概思路就是每遇到一个点就把他的值的位置变成 1,然后判断以这个点为中心的字符串是不是回文串。
其实就是参考的这里QwQ
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define MAXN 300005
#define int long long
using namespace std;
const int mod=1e9+7;
int n,power[300005];
struct segment_tree
{
int l[MAXN*4],r[MAXN*4];
int w[MAXN*4];
void build(int k,int ll,int rr)
{
l[k]=ll,r[k]=rr;
w[k]=0;
if(ll==rr) return ;
int mid=(ll+rr)/2;
build(k*2,ll,mid);
build(k*2+1,mid+1,rr);
return ;
}
void change(int k,int x)
{
if(l[k]==r[k]){w[k]=1;return ;}
int mid=(l[k]+r[k])/2;
if(x<=mid) change(k*2,x);
else change(k*2+1,x);
w[k]=power[r[k*2+1]-l[k*2+1]+1]*w[k*2]%mod+w[k*2+1]%mod;
return ;
}
pair<int,int>query(int k,int ll,int rr)
{
if(l[k]>=ll&&r[k]<=rr) return make_pair(w[k],r[k]-l[k]+1);
int mid=(l[k]+r[k])/2;
if(rr<=mid) return query(k*2,ll,rr);
if(ll>mid) return query(k*2+1,ll,rr);
pair<int,int>ansl=query(k*2,ll,rr),ansr=query(k*2+1,ll,rr);
return make_pair((power[ansr.second]*ansl.first%mod+ansr.first)%mod,ansl.second+ansr.second);
}
}tr,ee;
signed main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld",&n);
power[0]=1;
for(int i=1;i<=n;i++) power[i]=power[i-1]*23%mod;
tr.build(1,1,n);
ee.build(1,1,n);
bool flag=false;
for(int i=1;i<=n;i++)
{
int x;
scanf("%lld",&x);
int len=min(n-x,x-1);
if(len>0&&tr.query(1,x-len,x-1).first!=ee.query(1,n-x-len+1/*n-(x+len)+1*/,n-x/*n-(x+1)+1*/).first)
{
puts("Y");
flag=true;
break;
}
tr.change(1,x);
ee.change(1,n-x+1);
}
if(!flag) puts("N");
}
return 0;
}