• [CQOI2009] 中位数 (前缀和)


    [CQOI2009] 中位数

    题目描述

    给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有元素从小到大排列后,位于中间的数。

    输入输出格式

    输入格式:

    第一行为两个正整数n和b,第二行为1~n的排列。

    【数据规模】

    对于30%的数据中,满足n≤100;

    对于60%的数据中,满足n≤1000;

    对于100%的数据中,满足n≤100000,1≤b≤n。

    输出格式:

    输出一个整数,即中位数为b的连续子序列个数。

    输入输出样例

    输入样例#1:

    7 4
    5 7 2 4 3 1 6

    输出样例#1:

    4

    Solution

    首先题目有一个隐含的性质,因为是排列,而又保证(b)出现过,所以(b)在这(n)个数中有且只有一个

    这道题可以(O(n^2))通过统计前缀和拿到60分,我们只关心相对大小,所以可以把大于(b)的设成1,小于(b)的设成-1

    因为是中位数,所以前后的数字个数必定相等,在我们设了1/-1之后,又多了一个条件,即左边的数字的和+右边数字的和=0(想一想就知道了)

    那么我们就可以先统计一边的前缀和的个数,再在另一边一边计算前缀和一边统计答案,因为可能会有负数,所以有两种方法,一种是把数组平移,一种是开(map)

    具体结合代码(画一下)就懂了

    Code

    #include<bits/stdc++.h>
    #define in(i) (i=read())
    #define il extern inline
    #define rg register
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define lol long long
    using namespace std;
    
    const lol N=1e5+10;
    
    lol read() {
        lol ans=0, f=1; char i=getchar();
        while (i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
        while (i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+(i^48), i=getchar();
        return ans*f;
    }
    
    int n,m,sum,ans,pos,a[N];
    map<int,int>cnt;
    
    int main()
    {
        in(n), in(m);
        for (rg int i=1;i<=n;i++) {
            in(a[i]);
            if(a[i]>m) a[i]=1;
            else if(a[i]==m) a[i]=0, pos=i;
            else a[i]=-1;
        }
        for (int i=pos;i<=n;i++)
            sum+=a[i], cnt[sum]++;
        sum=0;
        for (int i=pos;i>=1;i--)
            sum+=a[i], ans+=cnt[-sum];
        cout<<ans<<endl;
    }
    
  • 相关阅读:
    【2021-03-31】人生十三信条
    【2021-03-30】证明自己是人类忠实的朋友
    【2021-03-29】万物本是无序
    缀点成线
    1比特与2比特字符
    Solution -「LOCAL」「cov. 牛客多校 2020 第三场 I」礼物
    Solution -「HNOI 2007」「洛谷 P3185」分裂游戏
    Solution -「CF 1372E」Omkar and Last Floor
    Solution -「POJ 3710」Christmas Game
    Solution -「CF 1380F」Strange Addition
  • 原文地址:https://www.cnblogs.com/real-l/p/9919024.html
Copyright © 2020-2023  润新知