zoukankan      html  css  js  c++  java
  • Codeforces1156E. Special Segments of Permutation

    Description

    You are given a permutation p of n integers 1, 2, ..., n (a permutation is an array where each element from 1 to n occurs exactly once).
    Let's call some subsegment p[l,r] of this permutation special if (p_l + p_r = max limits_{i = l}^{r} p_i). Please calculate the number of special subsegments.

    Input

    The first line contains one integer n ((3 le n le 2 cdot 10^5)).
    The second line contains n integers p1, p2, ..., pn (1≤pi≤n). All these integers are pairwise distinct.

    Output

    Print the number of special subsegments of the given permutation.

    Solution

    题目大意就是求区间[l,r]的个数,使得p[l]+p[r]=max(p[x])(x∈[l,r])
    考虑枚举这个max
    但暴力去做是(O(n^{2}))的,无法接受
    先预处理每个数的位置(因为每个数是唯一的,所以可以乱搞)
    然后我们暴力做出对于每个点可以向左(向右)能扩展到的位置
    最后暴力枚举较短的那段,可以因为预处理了位置,所以可以O(1)判断该点对于当前的max是否合法
    平均下来应该是O(n)的吧(雾大雾)

    Code

    #include <cstdio>
    #include <algorithm>
    #define N 200001
    #define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
    using namespace std;
    int n,i,tot,ans,a[N],bz[N],l[N],r[N],dui[N];
    void pd(int x,int y)
    {
        for (int i=x,pl;i<y;i++)
        {
            pl=bz[a[y]-a[i]];
            if (pl>y && pl<=r[y]) ans++;
        }
    }
    void ps(int x,int y)
    {
        for (int i=y,pl;i>x;i--)
        {
            pl=bz[a[x]-a[i]];
            if (pl<x && pl>=l[x]) ans++;
        }
    }
    int main()
    {
        open("Special");
        scanf("%d",&n);
        for (i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            bz[a[i]]=i;
        }
        for (i=1;i<=n;i++)
        {
            while (a[dui[tot]]<a[i] && tot) tot--;
            l[i]=dui[tot]+1;
            dui[++tot]=i;
        }
        tot=0;dui[0]=n+1;
        for (i=n;i>=1;i--)
        {
            while (a[dui[tot]]<a[i] && tot) tot--;
            r[i]=dui[tot]-1;
            dui[++tot]=i;
        }
        for (i=1;i<=n;i++)
            if (i-l[i]<r[i]-i) pd(l[i],i);else ps(i,r[i]);
        printf("%d",ans);
        return 0;
    }
    
    如果自己说什麽都做不到而什麽都不去做的话,那就更是什麽都做不到,什麽都不会改变,什麽都不会结束.
  • 相关阅读:
    继承---原型式继承
    CSS中可继承的属性
    函数定义相关
    现代密码学(对称密码——第一部分)
    数据结构练习题(1)
    数据结构与算法(线性表)
    数据结构与算法(绪论)
    大英四期中单词复习
    计算机组成原理_verilog学习_实验二答案(原创)
    现代密码学——第2章古典密码学
  • 原文地址:https://www.cnblogs.com/Sport-river/p/13861233.html
Copyright © 2011-2022 走看看