首页 > 其他分享 >The 2024 ICPC Asia East Continent Online Contest (I) G

The 2024 ICPC Asia East Continent Online Contest (I) G

时间:2024-11-10 23:08:33浏览次数:4  
标签:pre cnt le Contest int 个数 中位数 Asia ICPC

Link: The Median of the Median of the Median

考虑二分答案,对中位数进行二分,每次去判断是否比中位数大即可。

我们钦定了一个中位数 \(x\),对于 \(\{a\}\) 数组,若 \(a_i \ge x\),则令 \(a_i = 1\),否则 \(a_i = 0\),这样有一个好处,我们只关心 \(1\) 和 \(0\) 的数量,就可以知道中位数是否比 \(x\) 大。

如果 \(\{a\}\) 中 \(1\) 的个数多于 \(0\) 的个数,说明中位数大于等于 \(x\),否则中位数小于 \(x\)。

考虑对所有的 \(\{b_{i,j}\}_{l\le{i}\le{j}\le{r}}\) 求值,不妨枚举左端点 \(l\),求出一个以 \(l\) 为左端点的 \(\{b_{i,j}\}_{l\le{i}\le{j}\le{r}}\) 的中位数,我们通过前缀和可以求出有多少个数是大于 \(x\) 的。

设 \(cnt[i][j]\) 表示以 \(i\) 为左端点,所有 \(i \le k \le j\) 的 \(b_{i, k}\) 大于等于 \(x\) 的个数,\(pre[0/1]\) 表示 \(a[i \sim j]\) 中 \(0/1\) 的数量,容易发现:

\[cnt[i][j] = cnt[i][j - 1] + [pre[1] > pre[0]] \]

考虑如何计算 \(\{c_{l, r}\}_{1\le{l}\le{r}\le{n}}\),我们枚举 \(r\),对所有 \(1 \le l \le r\) 求和,因为我们计算的 \(cnt[i][j]\) 是以左端点固定的,因此计算一对 \((l, r)\) 时,对 \(l\) 求 \(cnt[i][r]\) 的后缀和即可,不过因为 \(cnt[i][j]\) 表示的是一个段,因此,\(0\) 的个数变化 \(j - i + 1 - cnt[i][j]\),\(1\) 的个数变化 \(cnt[i][j]\),对答案贡献 \(1\) 当且仅当每个段 \(1\) 的个数大于 \(0\) 的个数

当 \(1\) 的个数大于 \(0\) 时,说明中位数大于等于 \(x\),二分答案即可。

时间复杂度 \(O(n^2\log{|a|})\)。

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

void solve() {
    int n;
    cin >> n;
    vector<int> a(n + 1);
    for (int i = 1; i <= n; i ++ ) cin >> a[i];
    auto check = [&](int x) -> int {
        vector<int> b(n + 1);
        vector<vector<int>> cnt(n + 1, vector<int>(n + 1));
        for (int i = 1; i <= n; i ++ ) b[i] = (a[i] >= x);
        for (int i = 1; i <= n; i ++ ) {
            vector<int> pre(2);
            for (int j = i; j <= n; j ++ ) {
                pre[b[j]] ++ ;
                cnt[i][j] = cnt[i][j - 1] + (pre[1] > pre[0]);
            }
        }
        vector<int> sum(2);
        for (int i = 1; i <= n; i ++ ) {
            vector<int> pre(2);
            for (int j = i; j; j -- ) {
                pre[1] += cnt[j][i];
                pre[0] += i - j + 1 - cnt[j][i];
                sum[pre[1] > pre[0]] ++ ;
            }
        }
        return sum[1] > sum[0];
    };
    int l = 1, r = 1e9;
    while (l < r) {
        int mid = (l + r + 1) >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
    cout << r << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    solve();
    return 0;
}

标签:pre,cnt,le,Contest,int,个数,中位数,Asia,ICPC
From: https://www.cnblogs.com/YipChipqwq/p/18538718

相关文章

  • AtCoder Beginner Contest 379
    这次又是倒在了t5,没救了。ABC379A-Cyclic难度:红#include<bits/stdc++.h>usingnamespacestd;intmain(){chara,b,c;cin>>a>>b>>c;cout<<b<<c<<a<<''<<c<<a<<b;return0;}B-......
  • AtCoder Beginner Contest 379
    A-Cyclic题意输入\(3\)个连续字符\(a,b,c\),输出另外两种顺序。思路模拟。代码点击查看代码#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongtypedefpair<int,int>pii;constintmxn=1e6+5;voidsolve(){ chara,b,c; cin......
  • Toyota Programming Contest 2024#11(AtCoder Beginner Contest 379)题解
    总体情况A-Cyclic题意给你一个三位整数\(N\),其中每个数字都是介于\(1\)和\(9\)之间的整数。设\(a\),\(b\),\(c\)分别是\(N\)的百位、十位和个位数。打印一个按此顺序排列\(b\),\(c\),\(a\)所组成的整数,以及一个按此顺序排列\(c\),\(a\),\(b\)所组成......
  • The 2022 ICPC Asia Hangzhou Regional Programming Contest
    Preface久违地线下训练,没想到前年的比赛还有没打过的漏网之鱼这场由于一个中期题G被看出来是去年暑假前集训做过的原,导致题目难度跨度有点大最后一共出了8题,J几何的思路其实出的大差不差了,赛后改了改就过了A.ModuloRuinstheLegend首先转化下题意,令\(A=n,B=\frac{n......
  • AtCoder Beginner Contest 358 - VP记录
    Preface这次的动规题真的多,起码有三道都是。赛时做完ABCD以后就去攻G去了,可惜犯了煞笔错误搞WA了。赛后补F的时候思路代码啥的都挺顺的(没看题解独立切的蓝题),就是犯了更煞笔的错误,成消愁......
  • ICPC23沈阳区域赛 D. Dark LaTeX vs. Light LaTeX 题解
    D.DarkLaTeXvs.LightLaTeXThe2023ICPCAsiaShenyangRegionalContest(The2ndUniversalCup.Stage13:Shenyang)给两个字符串\(s,t\),长度分别为\(n,m\),现在分别取\(s,t\)的子串\(s',t'\),合成一个新的长度为偶数的字符串\(str=s'+t'\),记\(str\)的长度为......
  • The 2022 ICPC Asia Hangzhou Regional Programming Contest C
    C.NoBugNoGame\(很简单的一个dp\)\(在枚举到当前为i的时候假设当前容量为j对其进行转移\)点击查看代码#include<bits/stdc++.h>#defineintlonglong#defineall(x)x.begin(),x.end()#definerall(x)x.rbegin(),x.rend()#definepbpush_back#definepiipair<......
  • The 2022 ICPC Asia Hangzhou Regional Programming Contest
    A.ModuloRuinstheLegend\(题目即求(sum+n*s+(n+1)*n/2*d)\equiv\modm的最小值\)\(由裴蜀定理可得n*s+(n+1)*n/2*d=gcd(n,(n+1)*n/2)\)\(令p=gcd(n,n*(n+1)/2)\)\(可以表示为(sum+k*p+t*m)\equiv\modm\)\(令g=gcd(p,m)\)\((sum+g*z)%m\)\(sum+g*z>=m时存在最小值\)\(......
  • AtCoder Beginner Contest 378 ——F
    https://atcoder.jp/contests/abc378/tasks/abc378_fhttps://atcoder.jp/contests/abc378/editorial/11307#include<bits/stdc++.h>#definexfirst#defineysecond#defineall(x)(x).begin(),(x).end()#definelowbit(x)(x)&-(x)usingnamespacestd;ty......
  • AtCoder Beginner Contest 284题解
    AtCoderBeginnerContest284A没有什么难点,反着输出一遍就可以了。#include<bits/stdc++.h>usingnamespacestd;stringa[2000];intmain(){ intn; cin>>n; for(inti=1;i<=n;i++)cin>>a[i]; for(inti=n;i;i--)cout<<a[i]<<'\n';......