11377: 【原1377】序列
题目
题目描述
author: yuan 原OJ链接:https://acm.sjtu.edu.cn/OnlineJudge-old/problem/1377
题目描述
有一个长度为N的数列{A1,A2,...,AN},这N个数字恰好是1...N的一个排列。你需要求出这个序列有多少个子序列{Ai,Ai+1,...,Aj}满足:i<=j且j-i+1为奇数,这个序列的中位数为B。例如{5,1,3}的中位数为3。
输入说明
输入文件第一行包含两个正整数N和B,满足1<=N<=100000且1<=B<=N。
第二行包含N个整数Ai。
输出说明
输出文件仅包含一个整数,为满足条件的子序列个数。
样例输入
7 4
5 7 2 4 3 1 6
样例输出
4
数据范围
对于30%的数据,1<=n<=100;
对于70%的数据,1<=n<=10000;
对于100%的数据,1<=n<=100000;
Neight99's solution
#include <iostream>
using namespace std;
const int maxN = 1e5 + 100;
int N, B, A[maxN], a[maxN], pos, l[2 * maxN] = {0}, r[2 * maxN] = {0},
left1 = 0, right1 = 0;
int main() {
int sum=0;
cin >> N >> B;
for (int i = 1; i <= N; i++) {
cin >> A[i];
if (A[i] > B) {
a[i] = 1;
} else if (A[i] == B) {
a[i] = 0;
pos = i;
} else {
a[i] = -1;
}
}
left1 = right1 = N;
for (int i = pos; i > 0; i--) {
left1 += a[i];
l[left1]++;
}
for (int i = pos; i <= N; i++) {
right1 += a[i];
r[right1]++;
}
for (int i = 1; i <= 2 * N; i++) {
sum += (l[i] * r[2 * N - i]);
}
cout << sum;
return 0;
}
yyong119's solution
#include <cstdio>
#include <iostream>
#define MAX_N 100010
#define OFFSET 100010
using namespace std;
int n, B, B_pos;
int a[MAX_N];
int left_sum[MAX_N + OFFSET], right_sum[MAX_N + OFFSET];
inline int read() {
char ch = getchar(); int res = 0;
while (ch < '0' || ch > '9') ch = getchar();
while (ch >= '0' && ch <= '9')
res = (res << 3) + (res << 1) + (ch ^ 48), ch = getchar();
return res;
}
int main() {
n = read(), B = read();
for (register int i = 0; i < n; ++i) {
int tmp = read();
if (tmp < B) a[i] = -1;
else if (tmp > B) a[i] = 1;
else B_pos = i;
}
int cur_sum = 0;
for (register int i = B_pos - 1; i >= 0; --i) {
cur_sum += a[i];
++left_sum[OFFSET + cur_sum];
}
cur_sum = 0;
for (register int i = B_pos + 1; i < n; ++i) {
cur_sum += a[i];
++right_sum[OFFSET - cur_sum];
}
long long ans = 1;
for (register int i = 0; i < MAX_N + OFFSET; ++i)
ans += left_sum[i] * right_sum[i];
printf("%lld", ans + left_sum[OFFSET] + right_sum[OFFSET]);
return 0;
}