zoukankan      html  css  js  c++  java
  • BZOJ 2124: 等差子序列 线段树维护hash

    2124: 等差子序列


    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

    题解:

      题目说了是1到n的排列

      我们将1到n逐渐插入线段树的中,且用01表示出现状态

      假设当前x,我们只要找出与x相距距离相等的存在状态不同的就说明存在答案

      这就是线段树维护hash

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define N 10010
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define p 3
    #define mod 1000000007 
    using namespace std;
    typedef long long ll;
    ll hash[N<<2],hash2[N<<2];
    ll pow[N];
    int a[N];
    int n,t;
    void pushup(int rt,int m)
    {
        ll tmp=m>>1;
        hash[rt]=(hash[rt<<1]*pow[tmp]+hash[rt<<1|1])%mod;
        hash2[rt]=(hash2[rt<<1|1]*pow[m-tmp]+hash2[rt<<1])%mod;
    }
    void update(int pt,int l,int r,int rt)
    {
        if(l==r)
        {
            hash[rt]=hash2[rt]=1;
            return;
        }
        int mid=(l+r)>>1;
        if(pt<=mid)update(pt,lson);
        else update(pt,rson);
        pushup(rt,r-l+1);
    }
    ll query(int L,int R,int l,int r,int rt)
    {
        if(L>R)return 0;
        int ans=0;
        if(L==l&&r==R)
        {
            return hash[rt];
        }
        int mid=(l+r)>>1;
        if(R<=mid)return query(L,R,lson);
        else if(L>mid)return query(L,R,rson);
        else return (query(L,mid,lson)*pow[R-mid]+query(mid+1,R,rson))%mod;
    }
    ll query2(int L,int R,int l,int r,int rt)
    {
        if(L>R)return 0;
        if(L==l&&r==R)
        {
            return hash2[rt];
        }
        int mid=(l+r)>>1;
        if(R<=mid)return query2(L,R,lson);
        else if(L>mid)return query2(L,R,rson);
        else return (query2(L,mid,lson)+query2(mid+1,R,rson)*pow[mid-L+1])%mod;
    }
    int main()
    {
        scanf("%d",&t);
        pow[1]=p;
        for(int i=2;i<=10000;i++)pow[i]=(pow[i-1]*p)%mod;
        while(t--)
        {
            memset(hash,0,sizeof(hash));
            memset(hash2,0,sizeof(hash2));
            scanf("%d",&n);
            for(int i=1;i<=n;i++)scanf("%d",&a[i]);
            int flag=0;
            for(int i=1;i<=n;i++)
            {
                ll len=min(a[i]-1,n-a[i]);
                ll tmp1=query(a[i]-len,a[i]-1,1,n,1);
                ll tmp2=query2(a[i]+1,a[i]+len,1,n,1);
                if(tmp1!=tmp2)
                {
                    flag=1;break;
                }
                update(a[i],1,n,1);
            }
            if(flag)printf("Y
    ");
            else printf("N
    ");
        }
    }
  • 相关阅读:
    Selenium-Xpath使用方法
    HTML基础之js
    HTML基础—DOM操作
    CSS基础知识总结二
    CSS基础知识总结之css样式引用的三种方式
    BZOJ 2329/2209 [HNOI2011]括号修复 (splay)
    BZOJ 1576 [USACO]安全路经Travel (树剖+线段树)
    BZOJ 2402 陶陶的难题II (01分数规划+树剖+线段树+凸包+二分)
    BZOJ 4044 Virus synthesis (回文自动机+dp)
    BZOJ 2342 [SHOI2011]双倍回文 (回文自动机)
  • 原文地址:https://www.cnblogs.com/zxhl/p/5422126.html
Copyright © 2011-2022 走看看