bzoj 1303: [CQOI2009]中位数图 数学

1303: [CQOI2009]中位数图

Time Limit: 20 Sec  Memory Limit: 256 MB

题目连接

http://www.lydsy.com/JudgeOnline/problem.php?id=1303

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

题意

题解:

把大于b的置为1,把小于b的置为-1

然后左右都扫一遍,l[i]表示左边和为i的个数,r[i]表示右边和为i的个数

if(i+j==0)ans+=l[i]*r[i]

代码:

//qscqesze
#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <typeinfo>
#include <fstream>
#include <map>
#include <stack>
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define maxn 1000001
#define mod 10007
#define eps 1e-9
int Num;
char CH[20];
//const int inf=0x7fffffff;   //нчоч╢С
const int inf=0x3f3f3f3f;
/*

inline void P(int x)
{
    Num=0;if(!x){putchar(‘0‘);puts("");return;}
    while(x>0)CH[++Num]=x%10,x/=10;
    while(Num)putchar(CH[Num--]+48);
    puts("");
}
*/
inline ll 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;
}
inline void P(int x)
{
    Num=0;if(!x){putchar(‘0‘);puts("");return;}
    while(x>0)CH[++Num]=x%10,x/=10;
    while(Num)putchar(CH[Num--]+48);
    puts("");
}
//**************************************************************************************

int num[maxn];
int sum[maxn];
int l[maxn],r[maxn];
int point;
int main()
{
    int n,b;
    scanf("%d%d",&n,&b);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&num[i]);
        if(num[i]==b)
            point=i;
        if(num[i]>b)
            num[i]=1;
        else if(num[i]<b)
            num[i]=-1;
        else
            num[i]=0;
    }
    l[n]=1,r[n]=1;
    for(int i=point-1;i>=1;i--)
    {
        sum[i]=sum[i+1]+num[i];
        l[sum[i]+n]++;
    }
    for(int i=point+1;i<=n;i++)
    {
        sum[i]=sum[i-1]+num[i];
        r[sum[i]+n]++;
    }
    int ans=0;
    for(int i=0;i<=2*n;i++)
    {
        ans+=l[i]*r[2*n-i];
    }
    cout<<ans<<endl;
}
时间: 2024-10-12 04:46:48

bzoj 1303: [CQOI2009]中位数图 数学的相关文章

BZOJ 1303: [CQOI2009]中位数图【前缀和】

1303: [CQOI2009]中位数图 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2737  Solved: 1698[Submit][Status][Discuss] Description 给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. Input 第一行为两个正整数n和b ,第二行为1~n 的排列. Output 输出一个整数,即中位数为b的连续子序列个数.

[BZOJ 1303] [CQOI2009] 中位数图 【0.0】

题目链接:BZOJ - 1303 题目分析 首先,找到 b 的位置 Pos, 然后将数列中小于 b 的值赋为 -1 ,大于 b 的值赋为 1 . 从 b 向左扩展,不断算 Sum[i, b - 1] ,然后将 Cnt[Sum[i, b - 1]] 加一,这样就算出每个左边的Sum值有多少个了. 然后从 b 向右扩展,不断算 Sum[b + 1, i] ,然后 Ans += Cnt[Sum[b + 1, i]] . 代码 #include <iostream> #include <cstd

bzoj 1303: [CQOI2009]中位数图

1 #include<cstdio> 2 #include<iostream> 3 #define M 100005 4 using namespace std; 5 int a[M],l[2*M],r[2*M],sum[M],n,m,p,ans; 6 int main() 7 { 8 scanf("%d%d",&n,&m); 9 for(int i=1;i<=n;i++) 10 { 11 scanf("%d",&

BZOJ 1303: [CQOI2009]中位数图 【水题】

给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. Input 第一行为两个正整数n和b ,第二行为1~n 的排列. Output 输出一个整数,即中位数为b的连续子序列个数. Sample Input 7 45 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 思路:记录中间那个数左边右

1303: [CQOI2009]中位数图

1303: [CQOI2009]中位数图 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1383  Solved: 902[Submit][Status] Description 给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. Input 第一行为两个正整数n和b ,第二行为1~n 的排列. Output 输出一个整数,即中位数为b的连续子序列个数. Sample In

【BZOJ 1303】 [CQOI2009]中位数图

1303: [CQOI2009]中位数图 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 1452  Solved: 951 [Submit][Status] Description 给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. Input 第一行为两个正整数n和b ,第二行为1~n 的排列. Output 输出一个整数,即中位数为b的连续子序列个数. Sample

bzoj千题计划175:bzoj1303: [CQOI2009]中位数图

http://www.lydsy.com/JudgeOnline/problem.php?id=1303 令c[i]表示前i个数中,比d大的数与比d小的数的差,那么如果c[l]=c[r],则[l+1,r]满足条件 #include<cstdio> #include<iostream> using namespace std; const int N=1e7; int c[N*2],g[N]; void read(int &x) { x=0; char c=getchar()

bzoj[CQOI2009]中位数图

又是一道巧妙的题 将大于b的数标为1,将小于b的数标为-1 以b为界限,向两边分别求后缀和与前缀和,用l,r分别统计左右两边每个前缀和的数量 因为前缀和有负数所以整体加个n 于是答案就是l[i]*r[2*n-i]//和为2*n,即减去加上的n,和为0,此时b为中位数 因为题目中说要满足长度为奇数,此时若两个和加起来为2*n,个数相加一定为偶数,加上一个b就为奇数了 #include<bits/stdc++.h> using namespace std; const int maxn=10000

[BZOJ1303] [CQOI2009] 中位数图

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