zoukankan      html  css  js  c++  java
  • median(NOIP模拟赛Round 3)

    也是神奇的题目。。

    原题传送门

    首先看到这道题目,很明显我们需要线性算法

    1、前缀和+统计

    2、DP+统计

    对于第一种算法,我们可以对于任何一个a[i]对b进行比较,如果大于b标上1,等于b标上0,小于b标上-1;

    以0为中介,前缀和前后展开统计答案即可。。学长的神奇做法,不讲。。

    第二种算法啊,,

    其实和第一种算法差不多

    首先我们找到中位数b

    对其左边和右边进行搜索

    对于右边if(a[i]>a[i-1])f[i]=f[i-1]+1;else f[i]=f[i-1]-1;

    左边同上,不过i-1改为i+1。。(水~)

    然后我们很快会想到如果我们发现f[a[p](a[p]=b)]=f[i]=0时,答案肯定要+1。。这个很好理解吧。。

    那么我们发现其实中位数序列的起点或终点不一定一定是a[p]

    所以我们再对于每一次出现的f[i]做一下统计

    即if(f[i])tot[0][0][f[i]]++;else tot[0][1][-f[i]]++;(统计另一边的时候要写成f[i]>=0!注意!这非常重要!,因为前段的0归为负数,后端的0就要归为正数!,否则统计会出错!

    第一个维度是记录在a[p]左还是右边,第二个维度是记录是否为负数。。由于C++没有负数数组,所以不加会RE。

    然后判断的时候如果发现(tot[0][0][i]&&tot[1][1][i])||(tot[0][1][i]&&tot[1][0][i])

    显然我们的答案就是左边端点数*右边端点数

    然后就是代码啦!

    #include<iostream>
    #include<cstdio>
    using namespace std;
    int n,b,now;
    unsigned long long ans;
    int a[100001];
    int f[100001];
    int cnt[3][2][100001];
    int main(){
        freopen("median.in","r",stdin);
        freopen("median.out","w",stdout);
        scanf("%d%d",&n,&b);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(a[i]==b)now=i;
        }
        for(int i=now+1;i<=n;i++)
        {
            if(a[i]>b)f[i]=f[i-1]+1;
            else f[i]=f[i-1]-1;
            if(f[i]>=0)cnt[1][0][f[i]]++;
            else cnt[1][1][-f[i]]++;
        }
        for(int i=now-1;i>=1;i--)
        {
            if(a[i]>b)f[i]=f[i+1]+1;
            else f[i]=f[i+1]-1;
            if(f[i]>0)cnt[2][0][f[i]]++;
            else cnt[2][1][-f[i]]++;    
        }
        for(int i=1;i<=n;i++)if(f[i]==0)ans++;
        for(int i=0;i<=n-1;i++)
        {
            if(cnt[1][0][i]&&cnt[2][1][i])ans+=cnt[1][0][i]*cnt[2][1][i];
            if(cnt[1][1][i]&&cnt[2][0][i])ans+=cnt[1][1][i]*cnt[2][0][i];
        }
        printf("%lld
    ",ans);
        fclose(stdin);
        fclose(stdout); 
    }
  • 相关阅读:
    javaapplicationWeb application setup on Ubuntu VPS
    内容中断随想录(risc cpu的那些事)
    算法线性编程珠玑读书笔记之----->使用线性算法求解连续子序列的最大和
    classnull100
    安装javaUbuntu下安装JDK1.6,并将之设为默认的JDK
    筛选实现C++实现筛选法
    调试设置移动端Web开发环境搭建实践
    路由器交换机[置顶] 路由器和交换机的综合实验⑵
    卡数字怀念的东西:魔方
    密码配置配置SSH免密码登陆
  • 原文地址:https://www.cnblogs.com/ghostfly233/p/6901135.html
Copyright © 2011-2022 走看看