标签:space reg read 统计 格式 std pre += def
给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b。中位数是指把所有元素从小到大排列后,位于中间的数。
输入格式:
第一行为两个正整数n和b,第二行为1~n的排列。
【数据规模】
对于30%的数据中,满足n≤100;
对于60%的数据中,满足n≤1000;
对于100%的数据中,满足n≤100000,1≤b≤n。
输出格式:
输出一个整数,即中位数为b的连续子序列个数。
输入样例#1:
7 4
5 7 2 4 3 1 6
输出样例#1:
4
首先题目有一个隐含的性质,因为是排列,而又保证\(b\)出现过,所以\(b\)在这\(n\)个数中有且只有一个
这道题可以\(O(n^2)\)通过统计前缀和拿到60分,我们只关心相对大小,所以可以把大于\(b\)的设成1,小于\(b\)的设成-1
因为是中位数,所以前后的数字个数必定相等,在我们设了1/-1之后,又多了一个条件,即左边的数字的和+右边数字的和=0(想一想就知道了)
那么我们就可以先统计一边的前缀和的个数,再在另一边一边计算前缀和一边统计答案,因为可能会有负数,所以有两种方法,一种是把数组平移,一种是开\(map\)
具体结合代码(画一下)就懂了
#include<bits/stdc++.h>
#define in(i) (i=read())
#define il extern inline
#define rg register
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define lol long long
using namespace std;
const lol N=1e5+10;
lol read() {
lol ans=0, f=1; char i=getchar();
while (i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
while (i>='0' && i<='9') ans=(ans<<1)+(ans<<3)+(i^48), i=getchar();
return ans*f;
}
int n,m,sum,ans,pos,a[N];
map<int,int>cnt;
int main()
{
in(n), in(m);
for (rg int i=1;i<=n;i++) {
in(a[i]);
if(a[i]>m) a[i]=1;
else if(a[i]==m) a[i]=0, pos=i;
else a[i]=-1;
}
for (int i=pos;i<=n;i++)
sum+=a[i], cnt[sum]++;
sum=0;
for (int i=pos;i>=1;i--)
sum+=a[i], ans+=cnt[-sum];
cout<<ans<<endl;
}
标签:space reg read 统计 格式 std pre += def
原文地址:https://www.cnblogs.com/real-l/p/9919024.html