最近总在做一些bestCoder的题目,很多题可以通过自己的思考解决出来,不需要太依赖题解文献啥的了,比较开心的
题意:1-n的排列,求给定中位数的子串个数
题解&思路:1.感觉肯定不是暴力,时间过不去,感觉可能是记录前缀和的这种思想,就是用点值来表示一段数据;
2.从给定中位数的物理位置往后遍历,将大于中位数的数的个数与小于中位数的数的个数之差hash到一个数组中;
3.再从给定中位数的物理位置向前遍历,并找到中位数后面所对应的hash值
4.注意对只有中位数前半段和后半段的情况
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAXN 40005
int num[MAXN],dp[MAXN << 1];
int main()
{
int n,m,ind;
while(scanf("%d%d",&n,&m) != EOF)
{
memset(dp,0,sizeof(dp));
int more = 0;
ind = n;
for(int i = 0;i < n;i++)
{
scanf("%d",&num[i]);
if(num[i] == m)ind = i;
if(i > ind)
{
if(num[i] > m)more++;
dp[(i - ind) - 2 * more + n]++;
}
}
int ans = ++dp[n];
more = 0;
for(int i = ind - 1;i >= 0;i--)
{
if(num[i] > m)more++;
ans += dp[2 * more - (ind - i) + n];
}
printf("%d\n",ans);
}
}