BZOJ-1303 中位数图 数学+乱搞

30 篇文章 0 订阅
15 篇文章 0 订阅

1303: [CQOI2009]中位数图
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 1974 Solved: 1268
[Submit][Status][Discuss]

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

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

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

Sample Input
7 4
5 7 2 4 3 1 6

Sample Output
4

HINT
第三个样例解释:{4}, {7,2,4}, {5,7,2,4,3}和{5,7,2,4,3,1,6}
N<=100000

Source

题解:
发现了一个方法:
预处理一个权值数组,如果当前位置小于b为-1大于b为1,等于b为0
应用前缀和的思想,去做两个数组lsum,rsum。
不过,会出现负权,都+n即可

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int read()
{
    int x=0,f=1; char ch=getchar();
    while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
    while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
    return x*f;
}
#define maxn 100010
int n,b;
int a[maxn],qz[maxn],ans=0,loc;
int lsum[2*maxn],rsum[2*maxn],sum;
int main()
{
    n=read(),b=read();
    for (int i=1; i<=n; i++) 
        {a[i]=read();if (a[i]==b) loc=i;}
    for (int i=1; i<=n; i++)
        if (a[i]<b) qz[i]=-1; else qz[i]=1;
    lsum[n]=rsum[n]=1;
    sum=0;
    for (int i=loc-1; i>=1; i--)
        sum+=qz[i],lsum[sum+n]++;
    sum=0;
    for (int i=loc+1; i<=n; i++)
        sum+=qz[i],rsum[sum+n]++;
    for (int i=0; i<=2*n; i++) ans+=lsum[i]*rsum[2*n-i];
    printf("%d\n",ans);         
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值