BZOJ 1303: [CQOI2009]中位数图 问题转化_扫描_思维

将比 b 大的设成 1,比 b 小的设成 -1,开个桶左右扫描一下,乘法原理乘一乘就好了。

虽然一眼切,不过这个基于中位数的转化还是相当重要的。middle 那个主席树的题也需要该做法

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin)
#define maxn 1000000
using namespace std;
int arr[maxn],neg1[maxn],pos1[maxn],neg2[maxn],pos2[maxn],cur=0,zero1,zero2;
int main(){
    // setIO("input");
    int n,k;
    long long ans = 1;
    scanf("%d%d",&n,&k);
    for(int i = 1,a;i <= n; ++i) {
        scanf("%d",&a),arr[i]=(a<k)?-1:(a==k?0:1);
        if(a==k) cur=i;
    }  
    if(cur >= 1)
    {
        for(int i = cur-1,tot=0;i>=1;--i) 
        {
            tot+=arr[i];
            if(tot > 0) ++pos1[tot];
            if(tot < 0) ++neg1[-tot];
            if(tot==0) ++ans,++zero1;
        }
    }
    if(cur <= n)
    {
        for(int i = cur+1,tot=0;i<=n;++i)
        {
            tot+=arr[i];
            if(tot > 0) ++pos2[tot];
            if(tot < 0) ++neg2[-tot];
            if(tot == 0) ++ans, ++zero2;
        }
    }
    ans += (long long)zero1*zero2;
    for(int i = 1;i <= n; ++i)
    {
        ans += (long long)pos1[i]*neg2[i];
        ans += (long long)neg1[i]*pos2[i];
    }
    printf("%lld",ans);
    return 0;
}

  

posted @   EM-LGH  阅读(216)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示