博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CF993E Nikita and Order Statistics 多项式卷积 快速傅里叶变换
阅读量:4573 次
发布时间:2019-06-08

本文共 1107 字,大约阅读时间需要 3 分钟。

题意:

  给你一个数组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。

代码:

1 #include
2 #include
3 #define db double 4 #define ll long long 5 #define cp complex
6 using namespace std; 7 const int N=1000005; 8 const db pi=acos(-1); 9 int m,l,r[N],cnt[N],s[N],x;10 cp a[N],b[N],omg[N],inv[N];ll n,ans[N];11 void init(){12 for(int i=0;i
>j)&1) t|=(1<<(lm-j-1));20 if(i
>1ll;39 printf("%lld",ans[0]);40 for(int i=1;i<=q;i++)41 ans[i]=(ll)floor(a[q+i].real()/n+0.5),42 printf(" %lld",ans[i]);puts("");return 0;43 }
fft 快速傅里叶变换

转载于:https://www.cnblogs.com/Alan-Luo/p/10409145.html

你可能感兴趣的文章
好程序员技术分享html5和JavaScript的区别
查看>>
好程序员web前端分享CSS3文本属性
查看>>
ThinkPHP3.0启动过程
查看>>
Java入门 之 类和对象(一) - 类
查看>>
16级第二周寒假作业E题
查看>>
Java实现Windows锁屏
查看>>
在线会话管理
查看>>
文本处理之可视化wordcloud
查看>>
SampleManager(赛默飞)
查看>>
堆排序
查看>>
我的面试问题记录
查看>>
函数PARSENAME使用和截取字符串
查看>>
关乎性能的判断,请作出果断选择
查看>>
判断是否包含指定的字符
查看>>
[Html5] HTML5 开发手机应用
查看>>
[工具] 各种主流 SQLServer 迁移到 MySQL 工具对比
查看>>
(二)Maven 基本概念——依赖、生命周期、仓库管理、聚合&继承
查看>>
py4CV例子3Mnist识别和ANN
查看>>
【4Opencv】如何识别出轮廓准确的长和宽
查看>>
现货黄金交易计划摸索
查看>>