首页 > 其他分享 >CF1612G Max Sum Array

CF1612G Max Sum Array

时间:2024-01-20 16:00:53浏览次数:28  
标签:cnt 系数 CF1612G Max Sum leq fac Array

Max Sum Array

Luogu CF1612G

题面描述

  • 给定一个长为 \(m\) 的序列 \(c_1,c_2,\dots,c_m\)。
  • 序列 \(A\) 满足:对于所有 \(1 \leq i \leq m\),\(i\) 在 \(A\) 中出现了 \(c_i\) 次。
  • 定义一个序列 \(A\) 的值如下:

\[f(A)=\sum_{1 \leq i<j \leq n,a_i=a_j}j-i \]

  • 求满足条件的 \(f(A)\) 的最大值,及在取最大值时有多少种序列 \(A\)。
  • \(1 \leq m \leq 5 \times 10^5,1 \leq c_i \leq 10^6\)。

Solution

分开讨论每一种颜色。

假设一个颜色出现的位置为 \(p_1,p_2,p_3,\dots,p_n\)。拆一下贡献的式子,发现对于一个位置 \(p_i\),它最后会对答案造成 \((2i-n-1)p_i\) 的贡献。由于每个颜色出现的次数固定,因此所有的系数也是固定的,所以只需要找到一种 \(p\) 的分配方案使得答案最小即可。不难发现 \(p\) 只需要按照系数的大小关系分配,系数大的 \(p\) 也分配大的位置即可。

对于方案的求法,当两个位置的系数相等的时候,这两个位置一定可以交换且不影响答案。所以记 \(\operatorname{cnt}_i\) 表示系数为 \(i\) 的位置个数,那么最后的方案数应当为 \(\displaystyle\sum\operatorname{cnt}_i!\)。

如果直接按照上面的做法做,时间复杂度是 \(\mathcal O(m^2)\) 的。发现每一个颜色对系数桶的贡献其实相当于是一个步长为 \(2\) 的区间加,那么直接使用差分快速维护系数桶即可。

时间复杂度 \(\mathcal O(m)\)。

Code
int N, cnt[_N];
mint fac[_N];
void init(int n) {
    fac[0] = 1; For(i, 1, n) fac[i] = fac[i-1] * i;
}
signed main() {
    cin.tie(0)->sync_with_stdio(0);
    cin >> N; init(M);
    For(i, 1, N) {
        int x; cin >> x;
        ++cnt[M-x], --cnt[M+x];
    }
    i64 sum = 0;
    mint ans = 0, tot = 1;
    auto calc = [](i64 l, i64 r)->mint {
        return (l + r) * (r - l + 1) / 2 % mod;
    };
    For(i, 2, M << 1) {
        cnt[i] += cnt[i-2];
        ans += calc(sum + 1, sum + cnt[i]) * (mint(i) - M + 1);
        tot *= fac[cnt[i]];
        sum += cnt[i];
    }
    cout << ans << ' ' << tot << '\n';
}

标签:cnt,系数,CF1612G,Max,Sum,leq,fac,Array
From: https://www.cnblogs.com/hanx16msgr/p/17976572

相关文章

  • 记录一下 ArrayBlockingQueue 消息堆积的问题
    前言由于之前这个系统的日志记录是被领导要求写表的,在不影响系统性能的前提下,日志的入库操作肯定是要改成异步进行的,当时利用ArrayBlockingQueue+线程+AOP简单的去实现了一下,但是初版代码测试下来发现了一个很严重的问题,就是日志丢失的问题,本文由此而来。初步构思代码实现逻辑实......
  • linux修改max user processes limits
    突破ulimit限制修改普通用户单个用户可同时运行的最大进程数(默认为4096)[root@xxxdevops]#cat/etc/security/limits.d/20-nproc.conf#Defaultlimitfornumberofuser'sprocessestoprevent#accidentalforkbombs.#Seerhbz#432903forreasoning.*......
  • Petrozavodsk Summer 2019. Day 9. MEX Foundation Contest【杂题】
    比赛链接A.TheOnePolynomialMan给定模数\(p\)和\(0\simp-1\)的两个集合\(U,V\),求有多少个有序对\((a,b)\)满足:\(f(a,b)=\prod\limits_{z\inV}\left(\frac{(2a+3b)^2+5a^2}{(3a+b)^2}+\frac{(2a+5b)^2+3b^2}{(3a+2b)^2}-z\right)\equiv0\pmo......
  • D. Array Repetition
    D.ArrayRepetitionJaydenhasanarray$a$whichisinitiallyempty.Thereare$n$operationsoftwotypeshemustperforminthegivenorder.Jaydenappendsaninteger$x$($1\leqx\leqn$)totheendofarray$a$.Jaydenappends$x$copiesofarra......
  • D - Summer Vacation
    D-SummerVacation题意:有n个任务,每一天可以选择一个未完成的任务i来完成,并在ai天后获得bi的利益。问在m天内最多可以获得多少利益。首先我们可以考虑假如i,j两个任务都在我们最后的答案里面,那么让a比较大的排在前面一定是更好的。所以我们先按照a降序排序。然后用一个set维护......
  • Java里ArrayList中的toArray()用法
    深入理解List的toArray()方法和toArray(T[]a)方法这两个方法都是将列表List中的元素转导出为数组,不同的是,toArray()方法导出的是Object类型数组,而toArray[T[]a]方法导出的是指定类型的数组。下面是两个方法的申明及说明,摘自Java8的API文档。toArray()方法的分析Object[]toA......
  • PBK's sum of LCM
    \[\sum\limits_{i=1}^N\sum\limits_{j=1}^M\frac{a_ia_j}{\gcd(a_i,a_j)}\]\[\sum\limits_{d=1}^\infty\frac1d\sum\limits_{i=1}^N\sum\limits_{j=1}^Ma_ia_j[\gcd(a_i,a_j)=d]\]\[\sum\limits_{d=1}^\infty\frac1d\sum\limits_{i=1}^Na_i\......
  • 15 Friendly Arrays
    FriendlyArrays打表#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;voidsolve(){ intn,m; cin>>n>>m; vector<int>a(n+1); vector<int>b(m+1); for(inti=1;i<=n;i++)cin>>a[i]; for(inti=1;i<......
  • CF1921 F Sum of Progression 题解
    QuestionCF1921FSumofProgression给定一个序列\(\{a\}\),有\(q\)组询问,对于每组询问\(s,d,k\),求\[a_s+a_{s+d}\cdot2+\cdots+a_{s+d(k-1)}\cdotk\]Solution\(s,d,k\)其实就是在描述一个等差数列考虑到\(d\timesk\len\)如果\(d\)很大,那么就意味着\(k\)很......
  • Stack-array based implementation【1月17日学习笔记】
    点击查看代码//Stack-arraybasedimplementation#include<iostream>usingnamespacestd;#defineMAX_SIZE101intA[MAX_SIZE];//globleinttop=-1;//globlevoidpush(intx){ if(top==MAX_SIZE-1){ cout<<"error:stackoverflow"&l......