美文网首页
AtCoder Beginner Contest 107(D -

AtCoder Beginner Contest 107(D -

作者: kimoyami | 来源:发表于2018-08-25 23:36 被阅读38次

链接:https://abc107.contest.atcoder.jp/tasks/arc101_b
思路:我感觉是道神仙题, 我要在这里手动膜一下余大神!!!!口解题目tql!!!,首先不可能硬求中位数,我们考虑,如果所有的数为0和1的解法,那么我们可以考虑把0变为-1,然后对所有位置求前缀和,某两个前缀和后减前如果大于0则说明这个区间1更多(中位数是1),有了这个想法,我们就想到了可以用二分枚举,比当前枚举值大或者相等的设为1,小的设为-1,,然后用01的求法求解当前问题,算出逆序数,用总数-逆序和-(遍历1-n中<0的前缀和)就可以得到和大于等于0的区间数目,只要这个数目比总和数目的一半大就说明这个枚举值偏小,对应就行二分即可。细节很多写的时候注意,求逆序数用分治写的,还不太会用树状数组求后面来补一下这个地方= =
代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e5+10;
int a[maxn];
int b[maxn];
int n;

int c[maxn],tmp[maxn];
long long ans;

void Merge(int l,int m,int r)
{
    int i = l;
    int j = m + 1;
    int k = l;
    while(i <= m && j <= r)
    {
        if(c[i] > c[j])
        {
            tmp[k++] = c[j++];
            ans += m - i + 1;
        }
        else
        {
            tmp[k++] = c[i++];
        }
    }
       while(i <= m) tmp[k++] = c[i++];
    while(j <= r) tmp[k++] = c[j++];
    for(int i=l;i<=r;i++)
        c[i] = tmp[i];
}
 
void Merge_sort(int l,int r)
{
    if(l < r)
    {
        int m = (l + r) >> 1;
        Merge_sort(l,m);
        Merge_sort(m+1,r);
        Merge(l,m,r);
    }
}

int lowbit(int x){
    return x&(-x);
}

void add(int x,int d){
    while(x<=n){
        b[x]+=d;
        x+=lowbit(x);
    }
}


int sum(int x){
    int res = 0;
    while(x){
        res+=b[x];
        x-=lowbit(x);
    }
    return res;
}

bool cc(int d){
    memset(b,0,sizeof(b));
for(int i=1;i<=n;i++){
    if(a[i]>=d)add(i,1);
    else add(i,-1);
}
    for(int i=1;i<=n;i++)c[i] = sum(i);
        ans = 0;
        for(int i=1;i<=n;i++){
            if(c[i]<0)ans++;//单个前缀和小于0
        }
        Merge_sort(1,n);//统计逆序数
        long long num = 1LL*n*(n+1)/2 - ans;
        return num>=ans;
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    int ub = 1e9;
    int lb = 0;
        while(ub-lb>1){
            int mid = lb+(ub-lb)/2;
            if(cc(mid))lb = mid;
            else ub = mid;
        }
        if(cc(lb+1))lb++;
        printf("%d\n",lb);
    return 0;
}

相关文章

网友评论

      本文标题:AtCoder Beginner Contest 107(D -

      本文链接:https://www.haomeiwen.com/subject/wljniftx.html