【BZOJ 1303】 [CQOI2009]中位数图

【链接】 我是链接,点我呀:)
【题意】

在这里输入题意

【题解】

注意是1..n的排列。 设b的位置为i. 设i右边的数字,比b大的为1,比b小的为-1. (i左边的位置数字也一样设置成1和-1 则处理出pre[i..j]表示i..j这一段(1和-1)的和。 然后存在map中 做散列表。 然后在i的左边。 枚举这段区间从i开始 (因为显然是要经过i这个位置的。 所以只能从比i小的位置开始枚举。 (注意为i的情况也要枚举。

往左走求个前缀和(1和-1)now
然后答案累加dic[-now]就可以了

【代码】

#include <bits/stdc++.h>
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define all(x) x.begin(),x.end()
#define pb push_back
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;

const double pi = acos(-1);
const int dx[4] = {0,0,1,-1};
const int dy[4] = {1,-1,0,0};
const int N = 1e5;

int n,r,idx = 1;
int a[N+10];
map<int,int> dic;

int main(){
	#ifdef LOCAL_DEFINE
	    freopen("rush_in.txt", "r", stdin);
	#endif
    scanf("%d%d",&n,&r);
    rep1(i,1,n) scanf("%d",&a[i]);
    rep1(i,2,n) if (a[i]==r) idx = i;
    LL now = 0;
    dic[0]++;
    rep1(i,idx+1,n) {
        now += (a[i]>r?1:(-1));
        dic[now]++;
    }
    now = 0;
    LL ans = 0;
    rep2(i,idx-1,1){
        now+=(a[i]>r?1:(-1));
        ans+=dic[-now];
    }
    ans+=dic[0];
    printf("%lld\n",ans);
	return 0;
}

posted @ 2018-03-22 22:02  AWCXV  阅读(179)  评论(0编辑  收藏  举报