zoukankan      html  css  js  c++  java
  • bzoj 2124 等差子序列 树状数组维护hash+回文串

    等差子序列

    Time Limit: 3 Sec  Memory Limit: 259 MB
    Submit: 1919  Solved: 713
    [Submit][Status][Discuss]

    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

    HINT

     

    因此,我们构造一个辅助数组b,其中x如果出现过,那么b[x]=1;否则b[x]=0。因此如果x满足条件,那么必然存在一个数y使得b[x-y]!=b[x+y];然后我们发现如果把b看成一个字符串,那么实际上就是判断以x为中心的极长字符串是否是回文串,如果不是那么显然存在y使得b[x-y]!=b[x+y],那么就可以输出'Y'。快速的字符串比较不妨使用hash,然后因为需要修改那么就用两个树状数组分别维护它所在区间正着和倒着的hash值即可。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #define ll long long
     5 #define mod 1000000007
     6 #define N 10005
     7 using namespace std;
     8 
     9 int n,a[N],pw[N];
    10 struct bit_node{
    11     int c[N];
    12     void clr(){ memset(c,0,sizeof(c)); }
    13     void add(int x){
    14         int i; for (i=x; i<=n; i+=i&-i) c[i]=(c[i]+pw[i-x])%mod;
    15     }
    16     int getsum(int x){
    17         int i,t=0; for (i=x; i; i^=i&-i) t=((ll)c[i]*pw[x-i]+t)%mod;
    18         return t;
    19     }
    20     int qry(int x,int y){
    21         int p=getsum(x-1),q=getsum(y);
    22         return (q-(ll)p*pw[y-x+1]%mod+mod)%mod;
    23     }
    24 }bit1,bit2;
    25 int main(){
    26     int cas,i; scanf("%d",&cas);
    27     pw[0]=1; for (i=1; i<=10000; i++) pw[i]=(ll)pw[i-1]*12347%mod;
    28     while (cas--){
    29         scanf("%d",&n); int x;
    30         for (i=1; i<=n; i++) scanf("%d",&a[i]);
    31         bit1.clr(); bit2.clr();
    32         for (i=1; i<=n; i++){
    33             x=min(a[i]-1,n-a[i]);
    34             if (x && bit1.qry(a[i]-x,a[i]-1)!=bit2.qry(n-a[i]-x+1,n-a[i])) break;
    35             bit1.add(a[i]); bit2.add(n-a[i]+1);
    36         }
    37         puts((i>n)?"N":"Y");
    38     }
    39 }
  • 相关阅读:
    JAVA实现微信支付功能
    avue设置表格显示图片
    职工管理系统----删除职工
    职工管理系统---显示职工
    职工管理系统---读文件
    职工管理系统---写文件
    职工管理系统-------添加职工
    职工管理系统-----实现职工类
    职工管理系统-------实现退出功能
    职工管理系统-------菜单功能
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8847699.html
Copyright © 2011-2022 走看看