CF993E Nikita and Order Statistics 多项式卷积 快速傅里叶变换
题意:
给你一个数组a1~an,对于k=0~n,求出有多少个数组上的区间满足:区间内恰好有k个数比x小。x为一个给定的数。n<=10^5。值域没有意义。
分析:
大神们都说这道题是一个套路题,真是长见识%%%。
首先我们可以将题面转化,因为x是预先给出的,所以我们可以对其进行预处理,将数列中小于x的数都设为1,其他都为0,然后求一个前缀和,另前缀和数组为s[i]我们开一个数组v[i],记录在前缀和数组中数值i出现的次数。
然后我们可以得到这样一个式子
(据说看到这个式子就是套路了)
然后我们对这个式子进行一个转化。
转化:
之后,我们就可以修改上面的式子,变成这样,
有些经验的选手可以看得出,这个形式就是一个卷积的形式。
所以我们就直接把v数组和t数组看成多项式,用fft做一遍卷积,之后n+k次项的系数就是ans_k
k=0时需要特殊处理一下,要去除空串的影响,并且当k=0是,由于i和j的顺序问题,所以每种情况都统计了两次,最后要除以2。
代码:
#include<bits/stdc++.h>
#include<complex>
#define db double
#define ll long long
#define cp complex<db>
using namespace std;
const int N=;
const db pi=acos(-);
int m,l,r[N],cnt[N],s[N],x;
cp a[N],b[N],omg[N],inv[N];ll n,ans[N];
void init(){
for(int i=;i<n;i++)
omg[i]=cp(cos(*pi*i/n),sin(*pi*i/n)),
inv[i]=conj(omg[i]);
} void fft(cp *a,cp *tmp){
int lm=;while((<<lm)<n) lm++;
for(int i=;i<n;i++){int t=;
for(int j=;j<lm;j++)
if((i>>j)&) t|=(<<(lm-j-));
if(i<t) swap(a[i],a[t]);
} for(int l=;l<=n;l*=){
int m=l/;
for(cp *p=a;p!=a+n;p+=l)
for(int i=;i<m;i++){
cp t=tmp[n/l*i]*p[i+m];
p[i+m]=p[i]-t;p[i]+=t;
}
} return ;
} int main(){
scanf("%lld%d",&n,&x);cnt[]=;
for(int i=,y;i<=n;i++)
scanf("%d",&y),s[i]=s[i-]+(y<x),cnt[s[i]]++;
for(int i=;i<=n;i++) a[i]=b[n-i]=cnt[i];
int q=n;n=;while(n<=(q<<)) n<<=;
init();fft(a,omg);fft(b,omg);
for(int i=;i<n;i++) a[i]*=b[i];
fft(a,inv);
ans[]=(ll)((a[q].real()/n+0.5)-1ll*q-)>>1ll;
printf("%lld",ans[]);
for(int i=;i<=q;i++)
ans[i]=(ll)floor(a[q+i].real()/n+0.5),
printf(" %lld",ans[i]);puts("");return ;
}
fft 快速傅里叶变换
CF993E Nikita and Order Statistics 多项式卷积 快速傅里叶变换的更多相关文章
- CF993E Nikita and Order Statistics 【fft】
题目链接 CF993E 题解 我们记小于\(x\)的位置为\(1\),否则为\(0\) 区间由端点决定,转为两点前缀和相减 我们统计出每一种前缀和个数,记为\(A[i]\)表示值为\(i\)的位置出现 ...
- CF993E Nikita and Order Statistics
小于x的赋值为1,否则为0 区间等于k的个数 求0~n连续的n+1个k? N<=1e5? FFT! 考虑卷积建模:用下标相加实现转移到位,数值相乘类比乘法原理! 法一: 分治,然后FFT没了 法 ...
- CF993E:Nikita and Order Statistics(FFT)
Description 给你一个数组 $a_{1 \sim n}$,对于 $k = 0 \sim n$,求出有多少个数组上的区间满足:区间内恰好有 $k$ 个数比 $x$ 小.$x$ 为一个给定的数. ...
- 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】
原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...
- [学习笔记] 多项式与快速傅里叶变换(FFT)基础
引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积, 而代码量却非常小. 博主一年半前曾经因COGS的一 ...
- Codeforces 993E Nikita and Order Statistics [FFT]
洛谷 Codeforces 思路 一开始想偏想到了DP,后来发现我SB了-- 考虑每个\(a_i<x\)的\(i\),记录它前一个和后一个到它的距离为\(L_i,R_i\),那么就有 \[ an ...
- [Codeforces 993E]Nikita and Order Statistics
Description 题库链接 给你一个长度为 \(n\) 的序列 \(A\) ,和一个数 \(x\) ,对于每个 \(i= 0\sim n\) ,求有多少个非空子区间满足恰好有 \(i\) 个数 ...
- 多项式相乘快速算法原理及相应C代码实现---用到fft
最近认真研究了一下算法导论里面的多项式乘法的快速计算问题,主要是用到了FFT,自己也实现了一下,总结如下. 1.多项式乘法 两个多项式相乘即为多项式乘法,例如:3*x^7+4*x^5+1*x^2+5与 ...
- Algorithm: 多项式乘法 Polynomial Multiplication: 快速傅里叶变换 FFT / 快速数论变换 NTT
Intro: 本篇博客将会从朴素乘法讲起,经过分治乘法,到达FFT和NTT 旨在能够让读者(也让自己)充分理解其思想 模板题入口:洛谷 P3803 [模板]多项式乘法(FFT) 朴素乘法 约定:两个多 ...
随机推荐
- 【UVA - 540】Team Queue (map,队列)
Team Queue Descriptions: Queues and Priority Queues are data structures which are known to most comp ...
- hadoop wordcount程序缺陷
在wordcount 程序的main函数中,没有读取运行环境中的各种参数的值,全靠hadoop系统的默认参数跑起来,这样做是有风险的,最突出的就是OOM错误. 自己在刚刚学习hadoop编程时,就是模 ...
- rpm -e ** error :No such file or directory 解决
参考文章:http://www.redhat.com/archives/rpm-list/2006-June/msg00025.html 我遇到的情况是这样的: 1 先安装包 rpm -ivh tes ...
- 笔记-JavaWeb学习之旅2
数据库的基本概念 1.数据库:DataBase 简称 DB,用于存储和管理数据的仓库 特点: 1.持久化存储数据的,其实数据库就是一个文件系统, 2.方便存储和管理数据 3.使用了统一操作数据库 -- ...
- (一)搭建自己的SpringBoot后台框架整合MyBatis
一:通过idea工具构建基础框架 1. 打开idea,左上角File→New→Project, 2. 点击Next 3. 点击Next,配置如下图,这里我们选择数据库MySQL和持久层框架MyB ...
- 《算法竞赛进阶指南》1.6Trie
142. 前缀统计 给定N个字符串S1,S2-SN,接下来进行M次询问,每次询问给定一个字符串T,求S1-SN中有多少个字符串是T的前缀. 输入字符串的总长度不超过106,仅包含小写字母. 输入格式 ...
- 逆序数 HDOJ 4911 Inversion
题目传送门 题意:可以交换两个相邻的数字顺序k次,问最后逆序对最少有多少 分析:根据逆序数的定理如果逆序数大于0,那么必定存在1<=i<n使得i和i+1交换后逆序数减1假设原逆序数为cnt ...
- Problem D: 勤奋的涟漪2 dp + 求导
http://www.gdutcode.sinaapp.com/problem.php?cid=1049&pid=3 dp[i][state]表示处理了前i个,然后当前状态是state的时候的 ...
- python_8(模块)
第1章 模块 1.1 概述 1.2 模块的分类 1.2.1 内置模块 1.2.2 扩展模块 1.2.3 模块安装 1.2.4 自定义模块第2章 模块之内置模块 2.1 collections模块 2. ...
- new几种用法
在 C# 中,new 关键字可用作运算符.修饰符或约束. new 运算符 用于创建对象和调用构造函数. new 修饰符 用于向基类成员隐藏继承成员. new 约束 用于在泛型声明中约束可能用作类型参数 ...