[国家集训队] 等差子序列
给定一个 \(1\) 到 \(n\) 的排列 \(A\),判断是否存在 \(1 \leq p_1 < p_2 < \dots <p_{l} \leq n\),满足 \(l \geq 3\) 且 \([a_{p_1},a_{p_2},\dots,a_{p_l}]\) 是等差数列。
\(T \leq 7\) 组数据,\(n \leq 5 \times 10^5\)。
首先发现 \(l=3\)。若 \(l>3\),必然能够找到 \(l=3\) 的情况。
接下来考虑枚举中间的数,只需要检查两端是否分别出现 \(a_i-x\) 和 \(a_i+x\) 即可。考虑其反面,即所有 \(a_i-x\) 与 \(a_i+x\) 在同一端,此时我们考虑令 \(f_i=1\) 表示 \(i\) 在左侧,\(f_i=0\) 表示 \(i\) 在右侧,问题变为判定 \(f\) 关于 \(a_i\) 回文,哈希可以解决。
具体地,我们使用线段树,维护正反串哈希值即可。时间复杂度是 \(O(Tn \log n)\) 的。
#include<iostream>
#include<cstdio>
using namespace std;
const long long mod=998244353,base=233;
int p[500010];
long long pow_base[500010];
struct Node{
int l,r;
long long l_hash,r_hash;
}a[2000010];
Node merge(Node lhs,Node rhs){
Node hs;
hs.l=lhs.l;
hs.r=rhs.r;
hs.l_hash=lhs.l_hash+rhs.l_hash*pow_base[lhs.r-lhs.l+1]%mod;
hs.l_hash%=mod;
hs.r_hash=rhs.r_hash+lhs.r_hash*pow_base[rhs.r-rhs.l+1]%mod;
hs.r_hash%=mod;
return hs;
}
void build(int id,int l,int r){
if(l==r){
a[id].l=l;
a[id].r=r;
a[id].l_hash=a[id].r_hash=0;
}
else{
int mid=(l+r)>>1;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
a[id]=merge(a[id*2],a[id*2+1]);
}
}
void modify(int id,int pos){
if(a[id].l==a[id].r){
a[id].l_hash=a[id].r_hash=base;
return ;
}
if(pos<=a[id*2].r){
modify(id*2,pos);
}
else{
modify(id*2+1,pos);
}
a[id]=merge(a[id*2],a[id*2+1]);
}
Node query(int id,int l,int r){
if(l<=a[id].l && a[id].r<=r){
return a[id];
}
Node lans,rans;
bool lflag=false,rflag=false;
if(l<=a[id*2].r){
lans=query(id*2,l,r);
lflag=true;
}
if(a[id*2+1].l<=r){
rans=query(id*2+1,l,r);
rflag=true;
}
if(lflag && rflag){
return merge(lans,rans);
}
else if(lflag){
return lans;
}
else{
return rans;
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
pow_base[0]=1;
for(int i=1;i<=n;i++){
pow_base[i]=pow_base[i-1]*base%mod;
scanf("%d",&p[i]);
}
build(1,1,n);
bool ok=false;
for(int i=1;i<=n;i++){
int len=min(p[i],n-p[i]+1);
Node lans=query(1,p[i]-len+1,p[i]);
Node rans=query(1,p[i],p[i]+len-1);
if(lans.r_hash!=rans.l_hash){
ok=true;
}
modify(1,p[i]);
}
if(ok){
printf("Y\n");
}
else{
printf("N\n");
}
}
return 0;
}

浙公网安备 33010602011771号