• bzoj2124 等差子序列(树状数组+hash)


    题意

    给你一个1~n排列,问有没有一个等差数列(长度至少为3)

    题解

    我居然自己想到了正解。

    但我最后写挂了,所以我又看了题解。

    我们维护了一个以权值为下标的01序列。

    我们扫描整个序列。对于每一个正在扫描的数,我们判断以这个数的权值作为对称点,01序列是否对称。

    这个序列用权值树状数组维护就行。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cmath>
     5 #include<algorithm>
     6 #define LL long long 
     7 const LL mod=1e9+7;
     8 int n,t;
     9 const int N=10010;
    10 LL pw[N],c1[N],c2[N];
    11 int a[N];
    12 int min(int a,int b){
    13     if(a<b)return a;
    14     else return b;
    15 }
    16 int lowbit(int x){
    17     return x&(-x);
    18 }
    19 LL check1(int x){
    20     LL ans=0;
    21     for(int i=x;i>=1;i-=lowbit(i)){
    22         ans=(ans+(c1[i]*pw[x-i])%mod)%mod;
    23     }
    24     return ans;
    25 }
    26 LL check2(int x){
    27     LL ans=0;
    28     for(int i=x;i>=1;i-=lowbit(i)){
    29         ans=(ans+(c2[i]*pw[x-i])%mod)%mod;
    30     }
    31     return ans;
    32 }
    33 LL add1(int x){
    34        for(int i=x;i<=n;i+=lowbit(i)){
    35            c1[i]=(c1[i]+pw[i-x])%mod;
    36     }
    37 }
    38 LL add2(int x){
    39     for(int i=x;i<=n;i+=lowbit(i)){
    40         c2[i]=(c2[i]+pw[i-x])%mod;
    41     }
    42     return 0;
    43 }
    44 LL query1(int l,int r){
    45     LL p=check1(l-1),q=check1(r);
    46     return ((q-p*pw[r-l+1])%mod+mod)%mod;
    47 }
    48 LL query2(int l,int r){
    49     LL p=check2(l-1),q=check2(r);
    50     return ((q-p*pw[r-l+1])%mod+mod)%mod;
    51 }
    52 int main(){
    53     scanf("%d",&t);
    54     pw[0]=1;
    55     for(int i=1;i<=10001;i++)pw[i]=(pw[i-1]*(LL)2)%mod;
    56        for(int z=1;z<=t;z++){
    57         scanf("%d",&n);
    58         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    59         memset(c1,0,sizeof(c1));memset(c2,0,sizeof(c2));
    60         for(int i=1;i<=n;i++){
    61             int x=a[i];
    62             int len=min(n-x,x-1);
    63             if(len&&query1(x-len,x-1)!=query2(n-x-len+1,n-x)){printf("Y
    ");break;}
    64             add1(x);add2(n-x+1);
    65             if(i==n)printf("N
    ");
    66         }
    67     }
    68     return 0;
    69 }
    View Code
  • 相关阅读:
    进程与线程的区别iOS
    java面试题(中)
    java面试题(上)
    [Asp.net 5] DependencyInjection项目代码分析4-微软的实现(1)
    [Asp.net 5] DependencyInjection项目代码分析3-Ninject
    [Asp.net 5] DependencyInjection项目代码分析2-Autofac
    [Asp.net 5] DependencyInjection项目代码分析
    leetcode25 K个一组翻转链表
    leetcode128 最长连续序列
    leetcode124 二叉树中的最大路径和
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9402502.html
Copyright © 2020-2023  润新知