题目大意
给定一个排列和 ,
在该排列中。求该排列的长为奇数且以
为中位数的子段个数。
题解
考虑将排列映射成另一个序列,某一位置上的数为 那么映射后这一位置上的数变为
。那么必然映射后的序列会有一个
。
问题转化为求新生成的序列中,包含这个 在内且子段和为
的子段个数。这个可以用前缀和比较简单的做到。
#include <bits/stdc++.h> #define INF 2000000000 #define MOD 1000000007 #define MAXN 200005 #define REP(temp, init_val, end_val) for (int temp = init_val; temp <= end_val; ++temp) #define REPR(temp, init_val, end_val) for (int temp = init_val; temp >= end_val; --temp) using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> intpair; int read(){ int f = 1, x = 0; char c = getchar(); while (c < '0' || c > '9'){if(c == '-') f = -f; c = getchar();} while (c >= '0' && c <= '9')x = x * 10 + c - '0', c = getchar(); return f * x; } inline int lowbit(int x){ return x & (-x); } inline int modadd(int x, int y){ return (x + y >= MOD ? x + y - MOD: x + y); } inline int sgn(int x){ return (x < 0 ? -1: (x > 0 ? 1: 0)); } template<typename T> T gcd(T a, T b){ return (!b) ? a: gcd(b, a % b); } const int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1}; /*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/ int cnt[200005] = {0}, n, b; int main(){ n = read(), b = read(); int sum = 0, offset = n; cnt[offset] = 1; while (n--){ int t = read(); sum += sgn(t - b); if (t == b) break; ++cnt[offset + sum]; } ll ans = cnt[sum + offset]; while (n--){ int t = read(); sum += sgn(t - b); ans += cnt[sum + offset]; } printf("%lld\n", ans); return 0; }