• Bzoj2124(p5364): 等差子序列


    题目描述

    给一个1到N的排列{Ai},询问是否存在1<=p1<p2<p3<p4<p5<…<pLen<=N (Len>=3),

    使得Ap1,Ap2,Ap3,…ApLen是一个等差序列。

    输入

    输入的第一行包含一个整数T,表示组数。

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

    N<=10000,T<=7

    输出

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

    样例输入

    2
    3
    1 3 2
    3
    3 2 1

    样例输出

    N
    Y 

    考虑什么时候不存在等差数列
    把出现过的数字对应位置赋成1,没出现过的为0
    那么扫到i时,以a[i]为中心的串如果是回文,那么就不存在以a[i]为中心的等差数列
    考虑用线段树维护正反两种hash值,详情看代码吧233
    这题做的时候一次忘关调试信息了,然后删的时候还不小心删多了。。。(ノへ ̄、)
     1 #include<cstdio>
     2 #include<cstring>
     3 #define ull unsigned long long
     4 using namespace std;
     5 int T,n,a[10005];
     6 ull sum1[50000],sum2[50000],hsh[10005];
     7 void add(int x,int l,int r,int q){
     8     if(l==q&&r==q){
     9         sum1[x]=sum2[x]=1;
    10         return;
    11     }
    12     int mid=(l+r)/2;
    13     if(q<=mid)add(x+x,l,mid,q);
    14     else add(x+x+1,mid+1,r,q);
    15     sum1[x]=sum1[x+x]*hsh[r-mid]+sum1[x+x+1];
    16     sum2[x]=sum2[x+x]+sum2[x+x+1]*hsh[mid-l+1];
    17 }
    18 ull query(int x,int l,int r,int L,int R,int t){
    19     if(l==L&&r==R){
    20         if(t==1)return sum1[x];
    21         else return sum2[x];
    22     }
    23     int mid=(l+r)/2;
    24     if(R<=mid)return query(x+x,l,mid,L,R,t);
    25     else if(L>mid)return query(x+x+1,mid+1,r,L,R,t);
    26     else{
    27         if(t==1)return query(x+x,l,mid,L,mid,t)*hsh[R-mid]+query(x+x+1,mid+1,r,mid+1,R,t);
    28         else return query(x+x,l,mid,L,mid,t)+query(x+x+1,mid+1,r,mid+1,R,t)*hsh[mid-L+1];
    29     }
    30 }
    31 ull A,B;
    32 int main(){
    33     scanf("%d",&T);
    34     hsh[0]=1;
    35     for(int i=1;i<=10002;i++)hsh[i]=hsh[i-1]*131;
    36     while(T--){
    37         bool ok=1;
    38         scanf("%d",&n);
    39         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    40         for(int i=1;i<=n;i++){
    41             if(ok){
    42                 if(a[i]<=n/2){
    43                     A=query(1,1,n,1,2*a[i]-1,1);
    44                     B=query(1,1,n,1,2*a[i]-1,0);
    45                 }
    46                 else{
    47                     A=query(1,1,n,2*a[i]-n,n,1);
    48                     B=query(1,1,n,2*a[i]-n,n,0);
    49                 }
    50                 if(A!=B)ok=0;
    51                 add(1,1,n,a[i]);
    52             }
    53             else break;
    54         }
    55         if(ok)printf("N
    ");
    56         else printf("Y
    ");
    57         memset(sum1,0,sizeof(sum1));
    58         memset(sum2,0,sizeof(sum2));
    59     }
    60     return 0;
    61 }
    View Code
  • 相关阅读:
    Java函数式接口与逐步lambda简化
    Java继承知识点总结(基础知识3)
    Java静态工厂方法新建对象
    Java对象与类知识点总结(基础知识2)
    Java多线程并发入门(基础知识)
    Java基本程序设计结构(基础知识1)
    【数据库】JDBC课设(5)将图片以二进制流方法添加进MySQL并查询
    【数据库】JDBC课设(4) DatabaseMetaData 获得数据库信息
    【数据库】JDBC课设(3)TYPE_SCROLL_INSENSITIVE使结果集可以前后滚动
    简单总结.net下几种序列化
  • 原文地址:https://www.cnblogs.com/2017SSY/p/10176350.html
Copyright © 2020-2023  润新知