CF993E Nikita and Order Statistics
时间:2019-12-16
本文章向大家介绍CF993E Nikita and Order Statistics,主要包括CF993E Nikita and Order Statistics使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目大意:
给你一个数组 \(a_{1 \sim n}\),对于 \(k = 0 \sim n\),求出有多少个数组上的区间满足:区间内恰好有 \(k\) 个数比 \(x\) 小。\(x\) 为一个给定的数。
\(n \le 2 \times 10^5\)。
没见过大概想不到飞飞兔吧
考虑\(n\)为\(10w\)级别,且要求求\(0\sim n\)的每个\(k\),考虑\(fft\)
由于\(x\)是一定的,所以我们可以把小于\(x\)的数字变为\(1\),其他变为\(0\)
设\(s_i\)为变化后序列前缀和,\(f_i=\sum\limits_{j=0}^{n}[s_j==i]\)
那么我们要求
\[\sum\limits_{i=k}^{n}f_i*f_{i-k}\]
这个东西是不能\(fft\)的,对后面变化一下
\[\sum\limits_{i=k}^{n}f_i*f_{n-(n+k-i)}\]
令\(j=n+k-i\)
\[\sum\limits_{i+j=n+k}f_i*f_{n-j}\]
设\(g_i=f_{n-i}\)
\[\sum\limits_{i+j=n+k}f_i*g_j\]
它已经散发出毒品的香气了
不过注意当\(k=0\)时会重复计算左右端点,需要特判
一些细节证明先留锅,不太明白
#include<bits/stdc++.h>
using namespace std;
namespace red{
#define int long long
inline int read()
{
int x=0;char ch,f=1;
for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
if(ch=='-') f=0,ch=getchar();
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f?x:-x;
}
const int N=1e6+10;
double pi=acos(-1.0);
int n,tmp,limit,len;
int a[N],pos[N],ret[N];
int sum[N];
struct complex
{
double x,y;
complex(double tx=0,double ty=0){x=tx,y=ty;}
inline complex operator + (const complex &t) const
{
return complex(x+t.x,y+t.y);
}
inline complex operator - (const complex &t) const
{
return complex(x-t.x,y-t.y);
}
inline complex operator * (const complex &t) const
{
return complex(x*t.x-y*t.y,x*t.y+y*t.x);
}
}f[N],g[N];
inline void fft(int limit,complex *a,int inv)
{
for(int i=0;i<limit;++i)
if(i<pos[i]) swap(a[i],a[pos[i]]);
for(int mid=1;mid<limit;mid<<=1)
{
complex Wn(cos(pi/mid),inv*sin(pi/mid));
for(int r=mid<<1,j=0;j<limit;j+=r)
{
complex w(1,0);
for(int k=0;k<mid;++k,w=w*Wn)
{
complex x=a[j+k],y=w*a[j+k+mid];
a[j+k]=x+y;
a[j+k+mid]=x-y;
}
}
}
}
inline void main()
{
n=read(),tmp=read();
for(int i=1;i<=n;++i) a[i]=(read()<tmp),sum[i]=sum[i-1]+a[i];
f[0].x=1;
for(int tmp=0,i=1;i<=n;++i)
{
tmp+=a[i];
++f[tmp].x;
}
for(int i=0;i<=n;++i) g[i].x=f[n-i].x;
for(limit=1;limit<=n+n;limit<<=1) ++len;
for(int i=0;i<limit;++i) pos[i]=(pos[i>>1]>>1)|((i&1)<<(len-1));
fft(limit,f,1);
fft(limit,g,1);
for(int i=0;i<limit;++i) f[i]=f[i]*g[i];
fft(limit,f,-1);
for(int tmp=0,sum=0,i=1;i<=n;++i)
{
if(!a[i]) ++sum;
else
{
tmp+=((sum+1)*sum)>>1;
sum=0;
}
if(i==n)
{
tmp+=((sum+1)*sum)>>1;
printf("%lld ",tmp);
}
}
for(int i=n+1;i<=n+n;++i) ret[i]=f[i].x/limit+0.5;
for(int i=n+1;i<=n+n;++i) printf("%lld ",ret[i]);
}
}
signed main()
{
red::main();
return 0;
}
原文地址:https://www.cnblogs.com/knife-rose/p/12051604.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- mybatis 中#与$的区别
- Spring中的FactoryBean和BeanFactory
- MybatisPlus分页插件无效解决方案
- springboot+mybatis打印sql
- jquery插件与扩展
- CNN一定需要池化层吗?
- RabbitMQ入门Demo,基于springboot
- 收藏|Pandas缺失值处理看这一篇就够了!
- Spring Boot项目页面报错 OTS parsing error: Failed to convert WOFF 2.0
- Spring Boot开启JSP页面热部署
- Springboot thymeleaf热部署
- Java初始化List的6种方式
- Java遍历Map对象的四种方式
- 【SpringBoot源码解析】第三章:SpringBoot通过打成war包的方式是如何启动的
- 让你编码嗨到停不下来的8个VSCode插件