首页 > 其他分享 >【题解】CF1268C K Integers

【题解】CF1268C K Integers

时间:2023-01-11 18:56:55浏览次数:40  
标签:Integers limits int 题解 sum trick 花费 maxn CF1268C

萌新不懂就问,这是什么时代的题啊???

思路

trick 题。

首先根据 trick 可知:先将 \([1, k]\) 中的数聚在一起再排序是最优的。

排序的花费是逆序对数,所以现在的问题是求把 \([1, k]\) 聚在一起的最小花费。

又根据经典 trick 可知把它们聚在中位数的位置一定是最优的。

假设中位数为 \(t\),如果 \(t\) 左边有 \(x\) 个数,那么左侧移动的花费是 \(\sum\limits_{i = 1}^x t - i + 1 - p_i = tx - \frac{x(x - 1)}{2} - \sum\limits_{i = 1}^x p_i\)

同理右侧的花费是 \(\sum\limits_{i = 1}^x p_i - tx - \frac{x(x - 1)}{2}\)

那么只需要一个树状数组维护逆序对,另一个维护一下下标和即可。

这里直接 BIT 二分的复杂度是 \(O(n \log n)\),但是我写了两只 \(\log\).

代码

#include <cstdio>
using namespace std;

typedef long long ll;

const int maxn = 2e5 + 5;

int n;
int p[maxn], a[maxn];

struct BIT
{
    ll c[maxn];

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

    void update(int p, int w) { for (int i = p; i <= n; i += lowbit(i)) c[i] += w; }

    ll query(int p)
    {
        ll res = 0;
        for (int i = p; i; i -= lowbit(i)) res += c[i];
        return res;
    }
} c1, c2;

int main()
{
    ll cur = 0;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &p[i]);
        a[p[i]] = i;
    }
    for (int i = 1; i <= n; i++)
    {
        cur += (i - 1 - c1.query(a[i]));
        c1.update(a[i], 1);
        c2.update(a[i], a[i]);
        int l = 1, r = n;
        while (l < r)
        {
            int mid = (l + r + 1) >> 1;
            if (c1.query(mid - 1) * 2 <= i) l = mid;
            else r = mid - 1;
        }
        ll lcnt = c1.query(l), lsum = c2.query(l);
        ll rcnt = i - lcnt, rsum = c2.query(n) - lsum;
        ll cost = l * lcnt - lsum - lcnt * (lcnt - 1) / 2;
        cost += rsum - l * rcnt - rcnt * (rcnt + 1) / 2;
        printf("%lld ", cur + cost);
    }
    putchar('\n');
    return 0;
}

标签:Integers,limits,int,题解,sum,trick,花费,maxn,CF1268C
From: https://www.cnblogs.com/lingspace/p/cf1268c.html

相关文章

  • Codeforces 1278 F Cards 增强版 题解 (斯特林数,推式子)
    原题链接增强版链接增强版中k=1e7为啥网上题解的式子都那么长啊.jpg首先令\(p=\frac1m\)。求某个数的次幂的题通常都是无脑转下降幂:\(x^k=\sum_{i=0}^kS_2(k,i)x^{\u......
  • SOJ1711 题解
    题意给定\(n\)个在数轴的区间\([l_1,r_1],[l_2,r_2],...,[l_n,r_n]\)。定义\(I(x)\)为所有包含\([x,x+1]\)的区间形成的集合,即\(I(x)=\{k\mid[x,x+1]\subsete......
  • 搭建k8s集群初始化master节点 kubeadm init 遇到问题解决
    搭建k8s集群时遇到的问题一记,自己找了很久解决方案,也看到有些人提出类似问题后不了了之,于是发出来给网络做一次贡献kubeadminit报错”unknownserviceruntime.v1al......
  • CF850B Arpa and a list of numbers 题解 枚举
    题目链接:https://codeforces.com/problemset/problem/850/B题目大意我们定义一个数列是”坏的数列”当且仅当这个数列不为空且数列中所有元素的最大公约数为\(1\)。......
  • 题解 BZOJ3622【已经没有什么好害怕的了】
    前置知识:二项式反演problem两个\(n\leq2000\)的数组\(A,B\),元素互不相同,求有多少种将\(A,B\)配对的方法使得\(A>B\)的恰好有\(k\)对。题目改过,但是这一步转换......
  • Magic题解
    Magic题解题意简述:给定\(n\)个数\(a_1,a_2,…,a_n\),设对于数\(x\),\(|x|\)表示其在十进制下的位数,也即\(10^{|x|}\lex<10^{|x|+1}\)需要计算:\[\sum_{i=1}^n\sum_{j=i+1......
  • 选数 题解
    选数题解首先,设最初取值为\(x\),按照套路,我们设异或前缀和:\(pre_i=a_1\oplusa_2…\oplusa_i\),设\(f(x)=\left(\left\lfloor\frac{2x}{2^n}\right\rfloor+2x\right)\bmod......
  • Codeforces Round #843 (Div. 2) 题解
    A题目大意给你一个只含字母a,b字符串,要把它拆分成三段,使得其中间那段要么同时小于等于两边要么同时大于等于两边。题解由于只有a,b我们可以分讨解决如果\([2,......
  • CF1783 A-F 题解
    比赛链接:https://codeforces.com/contest/1783连续三场出4题,还行(其实感觉有两场的E都是会做的)A水题//bySkyRainWind#include<bits/stdc++.h>#definemprmake_pai......
  • 「JOI Open 2022」Giraffes 题解
    设我们将要给出的观感好的排列为\(q\),我们希望求出\(\sum[p_i=q_i]\)的最大值(这里指不移动的长颈鹿个数)。结论一:当且仅当左右端点有当前区间最大值或者最小值时条件才......