zoukankan      html  css  js  c++  java
  • BZOJ2124:等差子序列(线段树,hash)

    Description

    给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pLen<=N (Len>=3),
    使得Ap1,Ap2,Ap3,…ApLen是一个等差序列。

    Input

    输入的第一行包含一个整数T,表示组数。
    下接T组数据,每组第一行一个整数N,每组第二行为一个1到N的排列,数字两两之间用空格隔开。
    N<=10000,T<=7

    Output

    对于每组数据,如果存在一个等差子序列,则输出一行“Y”,否则输出一行“N”。

    Sample Input

    2
    3
    1 3 2
    3
    3 2 1

    Sample Output

    N
    Y

    Solution

    发现只用求是否存在长度为$3$的等差子序列就够了。

    对于一个$a_i$,若$a_i-k$和$a_i+k$都在他前面出现才不会有$(a_i-k,a_i,a_i+k)$这个等差子序列出现。

    所以可以从前往后枚举,出现为$1$未出现为$0$。可以用线段树维护区间$hash$判断以$a_i$为中心是否回文。

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #define N (10009)
     5 #define LL unsigned long long
     6 using namespace std;
     7 
     8 int T,n,flag,a[N];
     9 LL Segt[N<<2][2],base[N];
    10 
    11 inline int read()
    12 {
    13     int x=0,w=1; char c=getchar();
    14     while (c<'0' || c>'9') {if (c=='-') w=-1; c=getchar();}
    15     while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();
    16     return x*w;
    17 }
    18 
    19 void Update(int now,int l,int r,int x)
    20 {
    21     if (l==r) {Segt[now][0]=Segt[now][1]=1; return;}
    22     int mid=(l+r)>>1;
    23     if (x<=mid) Update(now<<1,l,mid,x);
    24     else Update(now<<1|1,mid+1,r,x);
    25     Segt[now][0]=Segt[now<<1][0]*base[r-mid]+Segt[now<<1|1][0];
    26     Segt[now][1]=Segt[now<<1|1][1]*base[mid-l+1]+Segt[now<<1][1];
    27 }
    28 
    29 LL Query(int now,int l,int r,int l1,int r1,int d)
    30 {
    31     if (l1<=l && r<=r1) return Segt[now][d];
    32     int mid=(l+r)>>1;
    33     if (r1<=mid) return Query(now<<1,l,mid,l1,r1,d);
    34     else if (l1>mid) return Query(now<<1|1,mid+1,r,l1,r1,d);
    35     else if(d==0) return Query(now<<1,l,mid,l1,mid,d)*base[r1-mid]+Query(now<<1|1,mid+1,r,mid+1,r1,d);
    36     else if(d==1) return Query(now<<1|1,mid+1,r,mid+1,r1,d)*base[mid-l1+1]+Query(now<<1,l,mid,l1,mid,d);
    37 }
    38 
    39 void Solve(int x)
    40 {
    41     Update(1,1,n,x);
    42     if (x==1 || x==n) return;
    43     int L=min(x-1,n-x);
    44     LL lh=Query(1,1,n,x-L,x-1,0);
    45     LL rh=Query(1,1,n,x+1,x+L,1);
    46     if (lh!=rh) flag=1;
    47 }
    48 
    49 int main()
    50 {
    51     T=read();
    52     base[0]=1;
    53     for (int i=1; i<=10000; ++i) base[i]=base[i-1]*1007;
    54     while (T--)
    55     {
    56         memset(Segt,0,sizeof(Segt));
    57         n=read(); flag=0;
    58         for (int i=1; i<=n; ++i)
    59         {
    60             int x=read();
    61             if (!flag) Solve(x);
    62         }
    63         puts(flag?"Y":"N");
    64     }
    65 }
  • 相关阅读:
    Web前端笔记和简历模板
    三种 Loading 制作方案
    注册中心之健康检测机制
    HTTPS与加密
    多线程-JUC
    date日期类型
    spring配置文件约束
    Tomcat web.xml 中的listener、 filter、servlet 加载顺序
    java 日志框架总结
    mysql常用命令
  • 原文地址:https://www.cnblogs.com/refun/p/10524520.html
Copyright © 2011-2022 走看看