• BZOJ 2124: 等差子序列


    2124: 等差子序列

    Time Limit: 3 Sec  Memory Limit: 259 MB
    Submit: 1041  Solved: 376
    [Submit][Status][Discuss]

    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

    Source

    分析:

    我们只需要判断是否存在一个长度为3的等差子序列就好...

    首先我们有一个很机智的想法...我们枚举中间的数x,判断是否存在x-y和x+y分别在x两边...我们从左向右扫描当前数字记为中间数字,维护一个vis数组,vis[i]=1代表i在当前数字之前出现过,=0代表没有出现过...然后只要当前数字的左右两边的01串不一样就代表存在一组合法解...

    这种判断回文串的问题可以通过hash解决,但是我们要动态维护hash值,所以要借助树状数组或者线段树...

    记得一定要开long long...

    代码:

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 //by NeighThorn
     6 #define int long long
     7 using namespace std;
     8 //眉眼如初,岁月如故
     9  
    10 const int maxn=10000+5,Mod=1e9+7;
    11  
    12 int n,cas,flag,p[maxn];
    13  
    14 struct Tree{
    15      
    16     long long tr[maxn];
    17      
    18     inline void clear(void){
    19         memset(tr,0,sizeof(tr));
    20     }
    21      
    22     inline void insert(int x,int y){
    23         int lala=x;
    24         for(;x<=n;x+=x&-x)
    25             (tr[x]+=y*p[x-lala])%=Mod;
    26     }
    27      
    28     inline int query(int x){
    29         int lala=x,res=0;
    30         for(;x;x-=x&-x)
    31             (res+=((long long)tr[x]*p[lala-x])%Mod)%Mod;
    32         return res;
    33     }
    34      
    35     inline int qry(int l,int r){
    36         return ((long long)query(r)-(long long)query(l-1)*p[r-l+1]%Mod+Mod)%Mod;
    37     }
    38      
    39 }a,b;
    40  
    41 signed main(void){
    42     scanf("%lld",&cas);p[0]=1;
    43     for(int i=1;i<=10000;i++)
    44         p[i]=(p[i-1]<<1)%Mod;
    45     while(cas--){
    46         scanf("%lld",&n);flag=0;
    47         a.clear();b.clear();
    48         for(int i=1,x;i<=n;i++){
    49             scanf("%lld",&x);
    50             if(flag)
    51                 continue;
    52             int lala=min(x-1,n-x);
    53             if(lala&&a.qry(x-lala,x-1)!=b.qry(n-(x+lala)+1,n-(x+1)+1))
    54                 puts("Y"),flag=1;
    55             a.insert(x,1),b.insert(n-x+1,1);
    56         }
    57         if(!flag)
    58             puts("N");
    59     }
    60     return 0;   
    61 }

    By NeighThorn

  • 相关阅读:
    2019沈阳网路赛 D. Fish eating fruit (点分治)
    2019南京网路赛 A.The beautiful values of the palace (主席树)
    洛谷 P2634 [国家集训队]聪聪可可(点分治)
    AcWing252 树 (点分治模板题)
    点分治模板 (洛谷 P3806)
    2020牛客寒假算法基础集训营2 J-求函数(线段树维护矩阵乘法)
    七夕祭(贪心+中位数)
    数据结构-集合
    数据结构-广义表
    数据结构-稀疏矩阵
  • 原文地址:https://www.cnblogs.com/neighthorn/p/6265737.html
Copyright © 2020-2023  润新知