2124: 等差子序列
Time Limit: 3 Sec Memory Limit: 259 MB
Submit: 1854 Solved: 689
[Submit][Status][Discuss]
Description
给一个1到N的排列{Ai},询问是否存在1<=p1
sol:
第一眼看上去就是2018芜湖nbc出的那题对吧,但是我没改那天的题。所以看到这题又不会做了。看了一眼题解就迅速的回忆起来了。
一个暴力就是对于出现在当前的中点左边的权值设为1,然后扫一下左边看一下右边能不能匹配上。
那么如果中点的权值为x,那么权值的那个桶实际上总是一个回文的,因为x+N,x-N全是0,或者全是1。所以我们用一个线段树来维护正反的hash值,看一下是不是回文串即可。
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long ll;
int n,m;
inline int read()
{
char c;
bool pd=0;
while((c=getchar())>'9'||c<'0')
if(c=='-') pd=1;
int res=c-'0';
while((c=getchar())>='0'&&c<='9')
res=(res<<3)+(res<<1)+c-'0';
return pd?-res:res;
}
const int N=11000;
const int M=41000;
const int pyz=1e9+7;
const int base=10;
int a[N];
int val[M][2],Pow[N];
inline void tag_down(int k,int l,int r)
{
int mid=l+r>>1;
if(val[k][0])
{
val[k<<1][0]=(val[k<<1][0]+val[k][0])%pyz;
val[k<<1|1][0]=(val[k<<1|1][0]+(ll)val[k][0]*Pow[mid+1-l]%pyz)%pyz;
val[k][0]=0;
}
if(val[k][1])
{
val[k<<1|1][1]=(val[k<<1|1][1]+val[k][1])%pyz;
val[k<<1][1]=(val[k<<1][1]+(ll)val[k][1]*Pow[r-mid]%pyz)%pyz;
val[k][1]=0;
}
}
inline int query(int k,int l,int r,int x,int y)
{
if(l==r) return val[k][y];
int mid=l+r>>1;
tag_down(k,l,r);
if(mid>=x) return query(k<<1,l,mid,x,y);
return query(k<<1|1,mid+1,r,x,y);
}
inline void modify0(int k,int l,int r,int x)
{
if(l>=x)
{
val[k][0]=(val[k][0]+Pow[l-x])%pyz;
return;
}
int mid=l+r>>1;
tag_down(k,l,r);
if(mid>=x) modify0(k<<1,l,mid,x);
modify0(k<<1|1,mid+1,r,x);
}
inline void modify1(int k,int l,int r,int x)
{
if(r<=x)
{
val[k][1]=(val[k][1]+Pow[x-r])%pyz;
return;
}
int mid=l+r>>1;
tag_down(k,l,r);
modify1(k<<1,l,mid,x);
if(mid+1<=x) modify1(k<<1|1,mid+1,r,x);
}
inline void modify(int x)
{
modify0(1,1,n,x);
modify1(1,1,n,x);
}
inline int query(int x)
{
int a,b;
if(n-x+1>=x)
{
b=(query(1,1,n,1,1)-(ll)query(1,1,n,x,1)*Pow[x-1]%pyz+pyz)%pyz;
a=(query(1,1,n,x+x-1,0)-(ll)query(1,1,n,x,0)*Pow[x-1]%pyz+pyz)%pyz;
return a==b;
}
else
{
a=(query(1,1,n,n,0)-(ll)query(1,1,n,x,0)*Pow[n-x]%pyz+pyz)%pyz;
b=(query(1,1,n,x-(n-x),1)-(ll)query(1,1,n,x,1)*Pow[n-x]%pyz+pyz)%pyz;
return a==b;
}
}
inline void solve()
{
n=read();
memset(val,0,sizeof(val));
for(int i=1;i<=n;++i) a[i]=read();
for(int i=1;i<=n;++i)
{
if(!query(a[i]))
{
printf("Y\n");
return;
}
modify(a[i]);
// cout<<query(1,1,n,1,1);
}
printf("N\n");
}
int main()
{
// freopen("2124.in","r",stdin);
// freopen("2124.out","w",stdout);
Pow[0]=1;
for(int i=1;i<=10000;++i) Pow[i]=(ll)Pow[i-1]*base%pyz;
int T=read();
while(T--) solve();
}