zoukankan      html  css  js  c++  java
  • [BZOJ2124]等差子序列

    2124: 等差子序列

    Time Limit: 3 Sec  Memory Limit: 259 MB Submit: 1504  Solved: 548 [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

    考虑插入并枚举每个数为等差中项,如果序列不存在等差数列,那么在它前面所有出现的数中,任意一个可能存在对应数的数都能找到对应的数,否则对应的数一定会出现在后面(因为是$1$到$n$的排列),所以可以考虑维护一个权值线段树,如果一个数出现过就标记为1,然后支持查询区间哈希值(正反)就行了

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    char buf[10000000], *ptr = buf - 1;
    inline int readint(){
        int n = 0;
        char ch = *++ptr;
        while(ch < '0' || ch > '9') ch = *++ptr;
        while(ch <= '9' && ch >= '0'){
            n = (n << 1) + (n << 3) + ch - '0';
            ch = *++ptr;
        }
        return n;
    }
    typedef unsigned long long ull;
    const int maxn = 10000 + 10;
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    ull h1[maxn << 2], h2[maxn << 2], pow[maxn];
    void Update(int w, int l, int r, int rt){
        if(l == r) h1[rt] = h2[rt] = 1;
        else{
            int mid = l + r >> 1;
            if(w <= mid) Update(w, lson);
            else Update(w, rson);
            h1[rt] = h1[rt << 1] * pow[r - mid] + h1[rt << 1 | 1];
            h2[rt] = h2[rt << 1 | 1] * pow[mid - l + 1] + h2[rt << 1];
        }
    }
    ull Query1(int ql, int qr, int l, int r, int rt){
        if(ql <= l && r <= qr) return h1[rt];
        else{
            int mid = l + r >> 1;
            if(ql > mid) return Query1(ql, qr, rson);
            else if(qr <= mid) return Query1(ql, qr, lson);
            else return Query1(ql, qr, lson) * pow[min(qr, r) - mid] + Query1(ql, qr, rson);
        }
    }
    ull Query2(int ql, int qr, int l, int r, int rt){
        if(ql <= l && r <= qr) return h2[rt];
        else{
            int mid = l + r >> 1;
            if(ql > mid) return Query2(ql, qr, rson);
            else if(qr <= mid) return Query2(ql, qr, lson);
            else return Query2(ql, qr, lson) + Query2(ql, qr, rson) * pow[mid - max(ql, l) + 1];
        }
    }
    int main(){
        fread(buf, sizeof(char), sizeof(buf), stdin);
        pow[0] = 1;
        for(int i = 1; i <= 10000; i++) pow[i] = pow[i - 1] * 6662333;
        int T = readint(), n;
        while(T--){
            n = readint();
            memset(h1, 0, sizeof h1);
            memset(h2, 0, sizeof h2);
            bool flag = false;
            for(int t, len, i = 1; i <= n; i++){
                t = readint();
                len = min(t - 1, n - t);
                if(!flag && len && Query1(t - len, t - 1, 1, n, 1) != Query2(t + 1, t + len, 1, n, 1)) flag = true;
                Update(t, 1, n, 1);
            }
            puts(flag ? "Y" : "N");
        }
        return 0;
    }
  • 相关阅读:
    HTML中,input元素的 Disabled属性 所产生的后端无法接收数据的问题
    计算字符串中大写字母,小写字母,数字的出现次数
    实现正整数的加法计算器
    简单的用户登陆程序
    对奇偶数的处理
    如何使用循环计算1 + 2 +3 + 4 + 5 + 6 + 8 + 9 + 10的值
    计算100以内所有整数的和
    根据用户输入的月份显示对应的美食
    根据用户输入的年龄输出不同的信息
    整齐的输出一首古诗
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/7506138.html
Copyright © 2011-2022 走看看