zoukankan      html  css  js  c++  java
  • [BZOJ 2124]等差子序列

    [BZOJ 2124]等差子序列

    题目

    给一个1到N的排列{Ai},询问是否存在(3<=plen),使得Ap1,Ap2,Ap3,…ApLen是一个等差序列。

    INPUT

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

    OUTPUT

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

    SAMPLE

    INPUT

    2

    3

    1 3 2

    3

    3 2 1

    OUTPUT

    N

    Y

    解题报告

    神题神思路= =

    我们用$01$串代表某个值是否出现过,然后$hash$

    对于每次出现的$a[i]$,我们找出向左与向右最长相等长度的$01$串的$hash$值,

    判断一下是否相等,如果相等,说明$a[i]-x$与$a[i]+x$在$a[i]$的同侧,就不可能出现长度为$3$的等差数列

    线段树瞎$XX$维护一下就好了

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 inline int read(){
     6     int sum(0);
     7     char ch(getchar());
     8     for(;ch<'0'||ch>'9';ch=getchar());
     9     for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar());
    10     return sum;
    11 }
    12 typedef long long L;
    13 const int p=3;
    14 const int mod=1000000007;
    15 L xp[10005];
    16 L has1[40005],has2[40005];
    17 int a[10005];
    18 inline void pushup(int i,int len){
    19     int tmp(len>>1);
    20     has1[i]=(has1[i<<1]*xp[tmp]+has1[i<<1|1])%mod;
    21     has2[i]=(has2[i<<1|1]*xp[len-tmp]+has2[i<<1])%mod;
    22 }
    23 inline void update(int pos,int l,int r,int i){
    24     if(l==r){
    25         has1[i]=has2[i]=1;
    26         return;
    27     }
    28     int mid((l+r)>>1);
    29     if(pos<=mid)
    30         update(pos,l,mid,i<<1);
    31     else
    32         update(pos,mid+1,r,i<<1|1);
    33     pushup(i,r-l+1);
    34 }
    35 inline L query1(int ll,int rr,int l,int r,int i){
    36     if(ll>rr)
    37         return 0;
    38     if(ll==l&&r==rr)
    39         return has1[i];
    40     int mid((l+r)>>1);
    41     if(rr<=mid)
    42         return query1(ll,rr,l,mid,i<<1);
    43     if(ll>mid)
    44         return query1(ll,rr,mid+1,r,i<<1|1);
    45     return (query1(ll,mid,l,mid,i<<1)*xp[rr-mid]+query1(mid+1,rr,mid+1,r,i<<1|1))%mod;
    46 }
    47 inline L query2(int ll,int rr,int l,int r,int i){
    48     if(ll>rr)
    49         return 0;
    50     if(ll==l&&r==rr)
    51         return has2[i];
    52     int mid((l+r)>>1);
    53     if(rr<=mid)
    54         return query2(ll,rr,l,mid,i<<1);
    55     if(ll>mid)
    56         return query2(ll,rr,mid+1,r,i<<1|1);
    57     return (query2(ll,mid,l,mid,i<<1)+query2(mid+1,rr,mid+1,r,i<<1|1)*xp[mid-ll+1])%mod;
    58 }
    59 int main(){
    60     int T(read());
    61     xp[0]=1;
    62     for(int i=1;i<=10000;++i)
    63         xp[i]=xp[i-1]*p%mod;
    64     while(T--){
    65         memset(has1,0,sizeof(has1));
    66         memset(has2,0,sizeof(has2));
    67         int n(read());
    68         for(int i=1;i<=n;++i)
    69             a[i]=read();
    70         bool flag(false);
    71         for(int i=1;i<=n;++i){
    72             int len(min(a[i]-1,n-a[i]));
    73             L tp1(query1(a[i]-len,a[i]-1,1,n,1)),tp2(query2(a[i]+1,a[i]+len,1,n,1));
    74             if(tp1^tp2){
    75                 flag=true;
    76                 break;
    77             }
    78             update(a[i],1,n,1);
    79         }
    80         if(flag)
    81             puts("Y");
    82         else
    83             puts("N");
    84     }
    85 }
    View Code
  • 相关阅读:
    except与besides
    think用法
    walk用法
    complain用法
    go through用法
    herd用法
    ridiculous用法
    it is the same as用法
    let us say用法
    1002 A+B for Polynomials (25 分)(模拟)
  • 原文地址:https://www.cnblogs.com/hzoi-mafia/p/7598669.html
Copyright © 2011-2022 走看看