• bzoj2124 等差子序列


    Description

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

    Input

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

    Output

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

    Sample Input

    2
    3
    1 3 2
    3
    3 2 1

    Sample Output

    N
    Y

    HINT 

    对于100%的数据,N<=10000,T<=7

    正解:树状数组+$hash$。

    超级神题系列。。

    这道题实际上是问能否找到一组$j<i<k$,使得$a[i]-a[j]=a[k]-a[i]$。

    考虑枚举中间的那个$i$,我们要找到一个公差$x$,使得$a[i]-x$出现过,而$a[i]+x$没有出现过。

    那么维护一个数组$b$,$b[i]=1$表示$i$出现过,否则没有出现过,于是只要有$b[a[i]-x]!=b[a[i]+x]$就行了。

    考虑把$b$变成一个字符串,那么如果以$x$为中心的极长串不是回文串,那么就有一组合法情况。

    那么我们维护一个正的字符串和反的字符串,因为有单点修改,所以我们用树状数组维护字符串的$hash$值就行了。

    查询的时候直接比较$a[i]$的左边串和右边的倒串是否相等即可。

     1 #include <bits/stdc++.h>
     2 #define il inline
     3 #define RG register
     4 #define ll long long
     5 #define ull unsigned long long
     6 #define N (100010)
     7 #define lb(x) (x & -x)
     8 
     9 using namespace std;
    10 
    11 int a[N],n,fg;
    12 ull bin[N];
    13 
    14 il int gi(){
    15   RG int x=0,q=1; RG char ch=getchar();
    16   while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    17   if (ch=='-') q=-1,ch=getchar();
    18   while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar();
    19   return q*x;
    20 }
    21 
    22 struct bit{
    23   
    24   ull c[N];
    25   
    26   il void init(){ memset(c,0,sizeof(c)); return; }
    27   
    28   il void add(RG int x){
    29     for (RG int i=x;i<=n;i+=lb(i)) c[i]+=bin[i-x]; return;
    30   }
    31   
    32   il ull query(RG int x){
    33     RG ull res=0; for (RG int i=x;i;i^=lb(i)) res+=c[i]*bin[x-i]; return res;
    34   }
    35   
    36   il ull calc(RG int l,RG int r){
    37     RG ull hsh1=query(l-1),hsh2=query(r);
    38     return hsh2-hsh1*bin[r-l+1];
    39   }
    40   
    41 }bit1,bit2;
    42 
    43 il void work(){
    44   bit1.init(),bit2.init(),n=gi(),fg=0;
    45   for (RG int i=1;i<=n;++i) a[i]=gi();
    46   for (RG int i=1,len;i<=n;++i){
    47     len=min(a[i]-1,n-a[i]);
    48     if (len && bit1.calc(a[i]-len,a[i]-1)!=bit2.calc(n-a[i]-len+1,n-a[i])){ fg=1; break; }
    49     bit1.add(a[i]),bit2.add(n-a[i]+1);
    50   }
    51   puts(fg ? "Y" : "N"); return;
    52 }
    53 
    54 int main(){
    55 #ifndef ONLINE_JUDGE
    56   freopen("sequence.in","r",stdin);
    57   freopen("sequence.out","w",stdout);
    58 #endif
    59   bin[0]=1; for (RG int i=1;i<N;++i) bin[i]=bin[i-1]*10007;
    60   RG int T=gi();
    61   while (T--) work();
    62   return 0;
    63 }
  • 相关阅读:
    Java异常面试题
    Quickhit快速击键
    多态and接口
    Java面向对象编程概述
    学生管理系统--分层开发
    类型转换
    文件上传
    ongl(示例3-6 多值类型的数据处理)
    ongl(原始类型和包装类型)
    Interceptor
  • 原文地址:https://www.cnblogs.com/wfj2048/p/7498724.html
Copyright © 2020-2023  润新知