博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 4913 [Sdoi2017] 遗忘的集合
阅读量:6788 次
发布时间:2019-06-26

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

题目链接

题解

ai=0/1a_i=0/1ai=0/1表示元素iii是否在集合中,那么元素iii的生成函数为

(11−xi)ai (\frac{1}{1-x^i})^{a_i} (1xi1)ai
现在已知了
F(x)=∏i=1∞(11−xi)ai F(x)=\prod_{i=1}^{\infin}(\frac{1}{1-x^i})^{a_i} F(x)=i=1(1xi1)ai
要求aia_iai

对上式两边取对数

ln⁡F(x)=∑i=1∞−ailn⁡(1−xi) \ln F(x)=\sum_{i=1}^{\infin}-a_i\ln(1-x^i) lnF(x)=i=1ailn(1xi)
对右边泰勒展开
ln⁡F(x)=∑i=1∞ai∑j=1∞xijj \ln F(x)=\sum_{i=1}^{\infin}a_i\sum_{j=1}^{\infin}\frac{x^{ij}}{j} lnF(x)=i=1aij=1jxij
枚举T=ijT=ijT=ij
ln⁡F(x)=∑T=1∞xT∑d∣TaddT \ln F(x)=\sum_{T=1}^{\infin}x^{T}\sum_{d|T}a_d\frac{d}{T} lnF(x)=T=1xTdTadTd
T[xT]ln⁡F(x)=∑d∣Tadd T[x^T]\ln F(x)=\sum_{d|T}a_dd T[xT]lnF(x)=dTadd
反演得到
ai=∑d∣iμ(id)d[xd]ln⁡F(x)i a_i=\frac{\sum_{d|i}\mu(\frac{i}{d})d[x^d]\ln F(x)}{i} ai=idiμ(di)d[xd]lnF(x)
因此只要多项式求ln⁡\lnln即可得到aia_iai的值。

注意常数优化,可以使用提到的卡常技巧。

代码

#include 
#include
#include
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)char buf[1<<21],*p1=buf,*p2=buf; int read(){
int x=0,f=1; char ch=getchar(); while((ch<'0')||(ch>'9')) {
if(ch=='-') {
f=-f; } ch=getchar(); } while((ch>='0')&&(ch<='9')) {
x=x*10+ch-'0'; ch=getchar(); } return x*f;}int write(int x){
if(x>9) {
write(x/10); } putchar(x%10+'0'); return 0;}const int maxn=524288;const double pi=acos(-1);struct complex{
double r,i; complex(double _r=0,double _i=0):r(_r),i(_i){
} complex operator +(const complex &oth) const {
return complex(r+oth.r,i+oth.i); } complex operator -(const complex &oth) const {
return complex(r-oth.r,i-oth.i); } complex operator *(const complex &oth) const {
return complex(r*oth.r-i*oth.i,r*oth.i+i*oth.r); }};inline complex conj(complex x){
return complex(x.r,-x.i);}const complex hreal=complex(0.5,0);const complex himag=complex(0,-0.5);const complex gimag=complex(0,1);complex w[maxn+10];inline int fft(complex *s,int len){
for(int i=0,j=0; i
>1; while((j^=l)
>=1; } } for(int i=1,d=maxn; i
>=1) { for(int j=0; j
>15,a[i]&32767); } for(int i=0; i
>15,b[i]&32767); } for(int i=la; i
>=1; } return res;}int tmp[maxn+10];inline int getinv(int *s,int len,int *res){ if(len==1) { res[0]=quickpow(s[0],mod-2); return 0; } int k=(len+1)/2; getinv(s,k,res); for(int i=0; i
=mod) { g[j]-=mod; } } } int tot=0; for(int i=1; i<=n; ++i) { if(g[i]) { ans[++tot]=i; } } write(tot); putchar('\n'); for(int i=1; i

转载于:https://www.cnblogs.com/Canopus-wym/p/10376062.html

你可能感兴趣的文章
阻止冒泡
查看>>
ishop服务器端接口配置
查看>>
给锁住的行解锁(oracle)
查看>>
WordPress 背后的故事竟然是这样
查看>>
python作业day1—用户登陆
查看>>
PHP如何判断远程图片文件是否存在
查看>>
使用 @Path and @GET, @POST, 等
查看>>
oracle 查询用户权限
查看>>
MySQL中视图、事务、触发器、索引等操作的基本使用
查看>>
Daily Scrum - 11/13
查看>>
SEO之图片优化
查看>>
linux关机重启命令
查看>>
Python处理word文件
查看>>
gcc6.3的安装
查看>>
通过response对象的sendRedirect方法重定向网页
查看>>
如何解决arcmap中的反走样问题。
查看>>
C++基础之函数和作用域
查看>>
Android 关于在ScrollView中加上一个ListView,ListView内容显示不完全(总是显示第一项)的问题的两种简单的解决方案...
查看>>
【转】asp.net(c#)加密解密算法之sha1、md5、des、aes实现源码详解
查看>>
sql标识符和格式
查看>>