牛客编程巅峰赛S2第2场 - 钻石&王者 C-数据分析

数据分析

https://ac.nowcoder.com/acm/contest/9224/C

C 数据分析

分析

  1. 先看题目:最大的最小。其在做这一类的题都有一种思想。因为暴力时直接枚举区间,但是反着来,求出一个数对某一段区间的影响,拿样例举例
    图片说明
    一个数能作为最大值,区间的范围之内就不能出现大于它的任何数,设
    lm[i]:位于i左边第一个大于a[i]的数的位置+1
    rm[i]:位于i右边第一个大于a[i]的数的位置-1
    那么这个数能作为最大值的区间就出来了,图片说明 ,而这里面的区间长度就是图片说明,也就是说,我们要在这个范围之内维护一个最小值,最后进行单点查询即可

代码

class Solution {
public:
    /**
     * 找到所有长度子数组中最大值的最小值
     * @param numbers int整型vector 牛牛给出的数据
     * @return int整型vector
     */
    #define ls now<<1
    #define rs now<<1|1

    int n,tp;
    int a[100005],lm[100005],rm[100005],stk[100005],tag[400005],s[400005];

    vector<int>ans;

    inline void pd(int now)
    {
        if(tag[now]>1e9) return ;
        tag[ls]=min(tag[ls],tag[now]);
        tag[rs]=min(tag[rs],tag[now]);
        s[ls]=min(s[ls],tag[now]);
        s[rs]=min(s[rs],tag[now]);
        tag[now]=0x3f3f3f3f;
        return ;
    }

    inline void ch(int now,int l,int r,int x,int y,int z)
    {
        if(l>=x&&r<=y)
        {
            s[now]=min(s[now],z);
            tag[now]=min(tag[now],z);
            return ;
        }pd(now);

        int mid=(l+r)>>1;
        if(x<=mid) ch(ls,l,mid,x,y,z);
        if(mid<y) ch(rs,mid+1,r,x,y,z);
        s[now]=min(s[ls],s[rs]);
    }

    inline int find(int now,int l,int r,int x)
    {
        if(l==r) return s[now];
        pd(now);

        int mid=(l+r)>>1;
        if(x<=mid) return find(ls,l,mid,x);
        return find(rs,mid+1,r,x);
    }

    vector<int> getMinimums(vector<int>& numbers) {
        // write code here
        n=numbers.size();
        for (int i=0;i<n;i++) a[i+1]=numbers[i];
        memset(s,0x3f,sizeof(s));
        memset(tag,0x3f,sizeof(tag));

        lm[1]=1;stk[++tp]=1;
        for (int i=2;i<=n;i++)
        {
            while(tp&&a[stk[tp]]<=a[i]) tp--;
            lm[i]=stk[tp]+1;
            stk[++tp]=i;
        }
        tp=0;stk[++tp]=n;stk[0]=n+1;
        rm[n]=n;
        for (int i=n-1;i>=1;i--)
        {
            while(tp&&a[stk[tp]]<=a[i]) tp--;
            rm[i]=stk[tp]-1;
            stk[++tp]=i;
        }

        for (int i=1;i<=n;i++)
            ch(1,1,n,1,rm[i]-lm[i]+1,a[i]);

        for (int i=1;i<=n;i++)
            ans.push_back(find(1,1,n,i));

        return ans;
    }
};

后话

因为我有一种打完比赛想立即看到解法的冲动,所以很快便写下了这篇题解造福他人,不甚详明,如有疑问,还请提出

比赛题解 文章被收录于专栏

牛客IOI周赛,团队赛,练习赛,挑战赛,各种模拟赛的部分题解

全部评论

相关推荐

点赞 评论 收藏
分享
03-14 10:50
已编辑
门头沟学院 Java
鼠鼠华子无线实习,bg双九,通软岗位,论文,专利,竞赛都水过一点,秋招《非all&nbsp;in》选手,《泡池子泡到肿》选手,分享一下自己的时间线,给大家多一个参考。---实习末期,接口人电话沟通,最终决定求稳继续投递实习原部门---免机试,九月走完线下流程,开始入池---十月起开始保温,打听手中已拿offer,比较薪资,给出华子的预估职级和薪资(完全不给A的空间)---十月第二次保温,询问签约情况,各种暗示劝说留空白三方---十月底签约另一家公司,遂被降低优先级---十一月若干次常规保温信息(还有机会/稍晚一点/等这周。。。)---十二月告知部门有13的指标,愿意接受可以立刻发offer(难绷,妄图性...
蓦然回首一枝花:能体会楼主的心情,我投了华为无线的成研所,双9bg,被华子最后开了个13级的侮辱价 12.3打oc电话的时候接口人表示乐观等待就行,然后中间4周就开始不回消息或者拖四五天才回,翻来覆去就是“等审批结果”。 12月27号,我看应该是泡不出来了所以联系了部门流转,这时候接口人开始主动给我打电话告诉我马上就能出结果了,于是我也没继续流转。 12.31给我打电话说得降薪审批,薪资大概就是对应着13级的样子,但我当时因为投的是成都的,没有意识到薪资是按照上海开的,还以为这个薪资在成都是14级,加上那个时候我也“孝”劲上来了,想着能收我就行,于是答应了。 1.13开了出来,联系我了薪资,确认了下发现是13级,当时实在是接受不了,于是最终还是拒了。 拒的时候接口人告诉我说这个hc真的是他们争取了很久才争取到的,不过我一想到我12.3就打了oc电话,中间4周一直不搭理我或吊着我,最后12.31才告诉我争取不下来14级要降薪,也许争取真的要争取那么久吧,呵。 这个过程中也为华为拒了不少offer,大厂的、央企的、银行的都拒过,网上总说“华为没有发小奖状之前hr的话一个字都不要信”,当时没有放在心上,以为不会摊到我头上,现在来看当时也挺年轻气盛的。我感觉要不是中途我一直在烦hr,可能我就和楼主一样被泡死了吧,不过最后给开了个13级也和泡死没差,不过是被多侮辱了一次。 最后借楼主这个贴就只想跟后面的人提一个建议吧,还是那句说烂了的,“华为没有发小奖状之前hr的话一个字都不要信”,真的不要以为这样的情况不会出现在自己身上,不要拿自己的一辈子前途去送华为hr业绩。
点赞 评论 收藏
分享
评论
16
1
分享

创作者周榜

更多
牛客网
牛客企业服务