CF1156E Special Segments of Permutation【题解】瞎搞 单调栈

题面:http://codeforces.com/contest/1156/problem/E

Luogu翻译:https://www.luogu.com.cn/problem/CF1156E

话说Luogu要改域名了。

大意:给定一个长度为n的排列p,求有多少区间[l,r]满足,p[l]+p[r]=max{p[i]},其中l<=i<=r

据说可以笛卡尔树。

可是我不会。

那么就瞎搞。

预处理出左边第一个比a[i]大的数的位置,记为L[i]

R[i]同理为右边。

这个可以用单调栈求。

然后就可以枚举l和r了。

但是显然这样会爆炸。

但是由于题目的限制,可以只枚举一边。

另外一边直接查询有没有。

比如枚举了l,那么p[r]=pmax-p[l]

只用知道右边有没有p[r]就可以了。

代码如下:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2*1e5+10;
int n,a[maxn],pos[maxn];
long long ans;
int L[maxn],R[maxn],s[maxn];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        pos[a[i]]=i;
    }
    int top=0;
    for(int i=1;i<=n;i++){
        while(top && a[s[top]]<a[i]) top--;
        L[i]=s[top];
        s[++top]=i;
    }
    top=0;s[top]=n+1;
    for(int i=n;i;i--){
        while(top && a[s[top]]<a[i]) top--;
        R[i]=s[top];
        s[++top]=i;
    }
    for(int i=1;i<=n;i++){
        if(i-L[i]<R[i]-i){
            for(int j=L[i]+1;j<i;j++)
                if(pos[a[i]-a[j]]>i && pos[a[i]-a[j]]<R[i]) ans++;
        }else{
            for(int j=i+1;j<R[i];j++)
                if(pos[a[i]-a[j]]<i && pos[a[i]-a[j]]>L[i]) ans++;
        }
    }
    printf("%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/ChrisKKK/p/11521144.html

时间: 2024-11-08 07:33:10

CF1156E Special Segments of Permutation【题解】瞎搞 单调栈的相关文章

CF1156E Special Segments of Permutation

思路:笛卡尔树?(好像并不一定要建出来,但是可以更好理解) 提交:2次 错因:没有判左右儿子是否为空来回溯导致它T了 题解: 建出笛卡尔树,考虑如何计算答案: 先预处理每一个值出现的位置 \(pos[]\): 对于每一个有左右儿子的点,设他在原序列中的值为 \(mx\),根据笛卡尔树的性质,他比自己的子树中的任何一个元素都大 .这样, 我们遍历他的轻儿子中的元素 \(vl\) ,查询 \(pos[mx-vl]\) 是否在重子树中. 其实可以不建树,直接求出每个点作为最大值能够向左右扩展的区间,枚

woj 1575 - Signal generators 单调队列优化dp + 瞎搞

戳这里:1575 题意:直线上排列着N个信号发射器,每个信号发射器被激活后将会使得影响范围内的所有发射器都被激活.询问激活任意一个发射器后被激活的发射器数最大是多少. 官方题解:可能会存在环的情况,考虑按坐标排序后i < j < k,j激活了k,然后k再激活i.但是这样可以转化为直接激活k的方案.所以无影响. 于是可以用dp求解.dp[i] = max( dp[j] + 1 ), position[j] + R[i] >= position[i],用单调队列优化时间复杂度为O(n). 向

Codeforces Gym 100610 Problem H. Horrible Truth 瞎搞

Problem H. Horrible Truth Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100610 Description In a Famous TV Show “Find Out” there are n characters and only one Horrible Truth. To make the series breathtaking all way long, the sc

HDU 4937 (杭电多校 #7 1003题)Lucky Number(瞎搞)

题目地址:HDU 4937 多校的题以后得重视起来...每道题都错好多次...很考察细节.比如这道....WA了无数次.... 这题的思路自己真心想不到...这题是将进制后的数分别是1位,2位,3位和更多位的分开来计算. 当是1位的时候,显然只有3到6,此时只能是-1 当是2位的时候,可以转换成一元一次方程求解 当是3位的时候,可以转换成一元二次方程求解 当是4位的时候,此时最多也只有7000个数,7000^3接近1e12.所以剩下的直接枚举进制数来判断即可. 代码如下: #include <i

HDU 4923 Room and Moor(瞎搞题)

瞎搞题啊.找出1 1 0 0这种序列,然后存起来,这种情况下最好的选择是1的个数除以这段的总和.然后从前向后扫一遍,变扫边进行合并.每次合并,合并的是他的前驱.这样到最后从t-1找出的那条链就是最后满足条件的数的大小. Room and Moor Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 307    Accepted Su

HDU 4925 Apple Tree (瞎搞)

找到规律,各一个种一棵树,或者施肥.先施肥,先种树一样. Apple Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 197    Accepted Submission(s): 135 Problem Description I've bought an orchard and decide to plant some

Codeforces 433C. Ryouko&#39;s Memory Note (中位数,瞎搞,思维)

题目链接: http://codeforces.com/problemset/problem/433/C 题意: 给你一堆数字,允许你修改相同的数字成为别的数字,也可以修改成自己,问你修改后相邻数字的距离的绝对值的和最小是多少. 思路: 首先明确一个结论,一个数轴上一些点,要求一个与他们距离之和尽量小的点,那么这个点就是这些点的中位数,即排序后位于中间的数. 这题的思路是把每一个数的与之相邻的保存下来,为了方便,可以用vector数组.然后为了使得距离之和最短,要取中位数.在一串数字中,距所有数

HDU 5024 Wang Xifeng&#39;s Little Plot(暴力枚举+瞎搞)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5024 Problem Description <Dream of the Red Chamber>(also <The Story of the Stone>) is one of the Four Great Classical Novels of Chinese literature, and it is commonly regarded as the best one. Thi

【瞎搞】HDU 4968 Improving the GPA

枚举一种GPA有多少个 总分1加上该GPA的最小分数 总分2加上该GPA的最大分数 若总分1<=输入分数×n<=总分2 则可以在枚举的状态达到目标分数 #include <stdio.h> #include <string.h> #include <math.h> #include <string> #include <algorithm> using namespace std; #define IN freopen ("