[线段树 哈希] Codeforces452F. Permutation

考虑第 i 位上的数 ai ,如果对于任意 k[1,min(ai1,nai)] aik ai+k 都在它左边或者都在它右边,那么就不会存在以 ai 为中位数的长度为3的等差数列。

那么我们从左往右扫这个数列,用权值线段树记录哪些数出现过,那么就是判断区间 [aik,ai] [ai,ai+k] 是否对称。

线段树上HASH一下就好了

复杂度 O(nlogn)

#include <cstdio>
#include <iostream>
#include <algorithm>

using namespace std;

typedef unsigned long long Ull;

const int N=300010;
const Ull P=1000003;

int n,a[N];
Ull p[N],lval[N<<2],rval[N<<2];

inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}

inline void rea(int &x){
    char c=nc(); x=0;
    for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}

void Modify(int g,int l,int r,int x){
    if(l==r) return lval[g]=rval[g]=1,void();
    int mid=l+r>>1;
    (x<=mid)?Modify(g<<1,l,mid,x):Modify(g<<1|1,mid+1,r,x);
    lval[g]=lval[g<<1|1]+lval[g<<1]*p[r-mid];
    rval[g]=rval[g<<1]+rval[g<<1|1]*p[mid-l+1];
}

Ull Queryl(int g,int L,int R,int l,int r){
    if(L==l && r==R) return lval[g];
    int mid=L+R>>1;
    if(r<=mid) return Queryl(g<<1,L,mid,l,r);
    else if(l>mid) return Queryl(g<<1|1,mid+1,R,l,r);
    return Queryl(g<<1|1,mid+1,R,mid+1,r)+Queryl(g<<1,L,mid,l,mid)*p[r-mid];
}

Ull Queryr(int g,int L,int R,int l,int r){
    if(L==l && r==R) return rval[g];
    int mid=L+R>>1;
    if(r<=mid) return Queryr(g<<1,L,mid,l,r);
    else if(l>mid) return Queryr(g<<1|1,mid+1,R,l,r);
    else return Queryr(g<<1,L,mid,l,mid)+Queryr(g<<1|1,mid+1,R,mid+1,r)*p[mid-l+1];
}

int main(){
    rea(n);
    for(int i=1;i<=n;i++) rea(a[i]);
    p[0]=1; for(int i=1;i<=n;i++) p[i]=p[i-1]*P;
    for(int i=1;i<=n;i++){
        Modify(1,1,n,a[i]);
        int k=min(a[i]-1,n-a[i]);
        if(Queryl(1,1,n,a[i]-k,a[i])^Queryr(1,1,n,a[i],a[i]+k)) return puts("YES"),0;
    }
    puts("NO");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值