首页 > 其他分享 >题解 CF993E 【Nikita and Order Statistics】

题解 CF993E 【Nikita and Order Statistics】

时间:2024-09-16 23:47:00浏览次数:7  
标签:Statistics const int 题解 rhs Nikita return Vector inline

初看这道题,以为又是什么数据结构数数题,没啥思路,结果推式子时搞出了一个类似可以卷积的玩意儿,所以果断 \(FFT\) 解决。

那我们来分析问题:

  1. 这道题里,值域没用,每一个数只要管它与 \(x\) 的相对大小关系即可。如果它小于 \(x\) 那么有贡献,赋值为一,否则为零。然后,可以求前缀和,区间部分和问题往往可以用前缀和配对端点解决。

  2. 令 \(f_i\) 表示前缀和为 \(i\) 的前缀端点数量,\(m\) 为总共比 \(x\) 小的数的个数。显然的,对于恰好有大于一个数比 \(x\) 小的情况中,答案 \(g_k = \sum\limits_{i=0}^{m-k} f_i \times f_{i+k}\)。 这个式子意思就是取两个端点使区间值符合条件,然后用加乘原理统计一下。

  3. 考虑常用技巧,变换顺序,令 \(h_i = f_{m-i}\) ,所以 \(f_{i+k} = h_{m-i-k}\) ,这样的话,\(g\) 就可以写成两者加法卷积了。大功告成。

  4. 不要忘了特殊处理 \(g_0\) ,经过推导可知 \(g_0 = \sum\limits_{i=0}^m \frac{f_i\times{(f_i + 1)}}{2}\) ,暴力算就好。

struct Vector {
	double x, y;
	Vector(double _x = 0, double _y = 0) : x(_x), y(_y) {}

	inline Vector Vary(void) { return Vector(x, -y); }

	inline bool operator < (const Vector&rhs)
	const { return x == rhs.x ? y < rhs.y : x < rhs.x; }
	inline Vector operator - (const Vector&rhs)
	const { return Vector(x - rhs.x, y - rhs.y); }
	inline Vector operator + (const Vector&rhs)
	const { return Vector(x + rhs.x, y + rhs.y); }

	inline Vector operator * (const double&rhs)
	const { return Vector(x * rhs, y * rhs); }
	inline Vector operator / (const double&rhs)
	const { return Vector(x / rhs, y / rhs); }

	inline Vector operator * (const Vector&rhs)
	const { return Vector(x * rhs.x - y * rhs.y, x * rhs.y + y * rhs.x); }
}; typedef Vector Complex;

const double PI = std :: acos(-1.0);
const int Maxn = 6e5 + 5;

int lim = 1, rev[Maxn];
inline void FFT(int limit, Complex *arr, int type) {
	for (int i = 0; i < limit; i++)
		if (i < rev[i]) swap(arr[i], arr[rev[i]]);
	for (int mid = 1; mid < limit; mid <<= 1) {
		Complex w0(cos(PI / mid), type * sin(PI / mid));
		for (int i = 0; i < limit; i += mid << 1) { Complex w(1, 0);
			for (int j = 0; j < mid; j++, w = w * w0) {
				Complex x = arr[i + j], y = w * arr[i + j + mid];
				arr[i + j] = x + y, arr[i + j + mid] = x - y;
			}
		}
	} if (type == -1) for (int i = 0; i < limit; i++) arr[i] = arr[i] / limit;
}

int n, m, x; Complex f[Maxn];

signed main(void) {
	read(n), read(x);
	for (int i = 1, v; i <= n; i++) {
		read(v); m += v < x ? 1 : 0; f[m].x++;
	}
	
	f[0].x++;
	while (lim <= m << 1) lim <<= 1;
	for (int i = 0; i < lim; i++)
		rev[i] = (rev[i >> 1] >> 1) | ((i & 1) ? (lim >> 1) : 0);
	
	ll ret = 0;
	for (int i = 0; i <= m; i++) f[m - i].y = f[i].x, ret += (ll) f[i].x * (f[i].x - 1) / 2;
	
	FFT(lim, f, 1);
	for (int i = 0; i < lim; i++) f[i] = f[i] * f[i];
	FFT(lim, f, -1);
	
	writeln(ret, ' ');
	for (int i = 1; i <= m; i++) writeln((ll) (f[m - i].y / 2.0 + 0.5), ' ');
	for (int i = m + 1; i <= n; i++) writeln(0, " \n"[i == n]);
//	fwrite(pf, 1, o1 - pf, stdout);
	return 0;
}

标签:Statistics,const,int,题解,rhs,Nikita,return,Vector,inline
From: https://www.cnblogs.com/EternalEpic/p/18416766

相关文章

  • CF1334F Strange Function 题解
    传送门定义一个函数\(f\),输入一个数组\(a\),输出一个数组\(b\)为\(a\)的子序列:\(b_1=a_1\),设\(b_i\)在\(a\)中的位置为\(pos_i\),则\(b_i\)为\(a_{pos_{i-1}+1}\sima_n\)中第一个严格大于\(b_{i-1}\)的数。\(n\le5\times10^5\),\(|p_i|\le10^9,1\lea_i,b_i\le......
  • 嘉应学院第一届新生娱乐赛第一场题解
    A一道简单的语法题,直接输出"hellonowcoder"即可。代码#include<stdio.h>intmain(){printf("hellonowcoder");}B也是一道语法题,考察分支结构。根据题意进行判断输出即可。代码#include<stdio.h>intmain(){inta,b;scanf("%d%d",&a,&......
  • [ARC096E] Everything on It 题解
    题目链接点击打开链接题目解法肯定考虑容斥钦定有\(a\)个数出现\(0\)次,有\(b\)个数出现恰好\(1\)次,其他\(n-a-b\)个数随便,容斥系数为\((-1)^{a+b}\)先给出方案数的表达式:\(\sum\limits_{a=0}^n\sum\limits_{b=0}^{n-a}(-1)^{a+b}2^{2^{n-a-b}}\binom{n}{a}\binom{......
  • 图:310.最小高度数, 题解
    310.最小高度树-力扣(LeetCode)参考题解:算法逻辑:算法的核心思路是逐层剪去叶子节点,直到剩下的节点是最小高度树的根。示例:假设有如下的树结构:0/\12/\34初始时,叶子节点是1、3和4,剪掉这些叶子节点后,树变成:0\2再次剪掉......
  • 【洛谷 P1216】[USACO1.5] [IOI1994]数字三角形 Number Triangles 题解(动态规划)
    [USACO1.5][IOI1994]数字三角形NumberTriangles题目描述观察下面的数字金字塔。写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。在上面的样例中,从的路径产生了最大权值。输入格式第一个行一个正整数......
  • SciTech-Mathmatics-Probability+Statistics-Population:Region-Sampling of Region :
    SciTech-Mathmatics-Probability+StatisticsPopulation:Region-SamplingofRegion:ConfidenceInterval(置信区间)置信区间的理解与应用在我们的统计学系列,已经探索了多个关键概念,从基本的统计学原理到更复杂的假设检验方法。在上一篇文章《统计学入门(三):假设检验的原理与应......
  • 题解:P9938 [USACO21OPEN] Acowdemia II B
    首先根据每篇出版物构建一个资历比较矩阵\(g\),其中\(g_{a,b}=1\)表示研究员\(a\)比\(b\)资历更高。遍历每篇出版物,识别出第一个降序的名字,然后假定该名字之后的所有研究员资历都比当前名字对应的研究员资历高即可。代码:#include<bits/stdc++.h>usingnamespacestd;......
  • 题解:P9951 [USACO20FEB] Swapity Swap B
    奶牛的排列经过\(x\)次后会回到原来的位置,理解以下:\([a_1,a_2]\)的牛翻转两次就会回到原来的位置,\([b_1,b_2]\)的牛翻转两次也会回到原来的位置,所以原来奶牛的排列经过一定次数的旋转后一定会回到原来位置。我们只要先模拟得出多少次后第\(i\)位的奶牛会回到原来的位置,然后......
  • 题解:P9953 [USACO20OPEN] Social Distancing II B
    解决思路:根据奶牛的位置对数组进行排序。计算相邻健康奶牛和感染奶牛之间的最小距离。这个距离值减一用来估计感染传播的半径。(确保了感染奶牛之间的距离在当前半径下不会导致传播给其他健康奶牛。)遍历排序后的奶牛列表,找到每一段连续感染奶牛的区域,并计算这些区域中可能需要的......
  • 区间检测题解
    记录\(pre_i\)为\(a_i\)上一次出现的位置。每一次求\([L,R]\)范围内是否有相同的数即\(pre_L\)到\(pre_R\)中的最大值是否小于\(L\)。注意到\(pre_1\)到\(pre_{L-1}\)中最大数一定小于\(L\),所以求\([L,R]\)范围内是否有相同的数即\(pre_1\)到\(pre_R\)中的......