http://codeforces.com/problemset/problem/623/E (题目链接)

题意

  长度为${n}$的满足前缀按位或为单调递增的${k}$位序列。要求每个位置为${[1,2^k-1]}$之间的整数,求方案数。

Solution

  毛爷爷论文题,然而论文上的${dp}$方程都是错的,坑爹啊!!

  首先,每个数的二进制位上一定存在一位为${1}$,且之前的数的这一位上都为${0}$,这样才能保证按位或的前缀和单调递增。那么当${n>k}$时,显然答案是等于${0}$的,所以我们只讨论${n<=k}$同级的情况。

  ${f_{i,j}}$表示已经放了前${i}$个数,占用了二进制位中的${j}$位。那么我们考虑转出,则${f_{i+1,j+l}}$得到的${f_{i,j}}$的贡献就是:${f_{i,j}*2^j*C_{k-j}^{l}}$。${2^j}$指的是新添加的一个数在之前已经被占用的${j}$位上,可以随意取${0}$或${1}$。

  考虑优化,如果对于所有的${0<=i<=k}$,我们知道了${f_{x,i}}$和${f_{y,i}}$,我们可以直接求出${f_{x+y},i}$的值:$${f_{x+y,i}=\sum_{j=0}^{i}  {f_{x,j}*2^{yj}*f_{y,i-j}*\frac{C_{k-j}^{i-j}}{C_{k}^{i-j}} }  }$$

  其中,${f_{x,j}}$表示前${x}$个数的选择方案,$2^{yj}$表示后$y$个数中,已经被前$x$个数占据的$j$位可以任意填$0$或$1$。因为${f_{y,i-j}}$中的${i-j}$位是在所有位数${k}$位中选取的,可能就会与之前选取的${x}$个数占用的${j}$位有重叠,而这是不兹瓷的,所以这${i-j}$位只能在剩下的${k-j}$位中选了。我们化简这个式子,得到:$${k!*(k-i)!*f_{x+y,i}=\sum_{j=0}^{i} { [f_{x,j}*2^{yj}*(k-j)!]*[ f_{y,i-j}*(k-(i-j))! ]  }  }$$

  于是等式右边的式子我们可以${FFT}$求出,用类似于快速幂的思想,依次求出${1,2,4,8,16······}$然后看${n}$的当前二进制位上是否为${1}$,如果是${1}$就给答案卷积上这一位的值。复杂度${O(klog^2k)}$

细节

  注意${FFT}$精度感人,我们需要预处理${w_n^k}$。

代码

// codeforces 623E
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<complex>
#include<cstdio>
#include<cmath>
#include<queue>
#define LL long long
#define inf 1ll<<60
#define MOD 1000000007
#define M (1<<15)
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; typedef complex<double> E;
const int maxn=100010;
E a[maxn],b[maxn],c[maxn],d[maxn],A[maxn],B[maxn],C[maxn],w[maxn];
LL F[maxn],G[maxn],f[maxn],g[maxn];
LL fac[maxn],ifac[maxn],rev[maxn],K,N,L;
LL n; LL power(LL a,LL b) {
LL res=1;
while (b) {
if (b&1) res=res*a%MOD;
b>>=1;a=a*a%MOD;
}
return res;
}
void DFT(E *t,LL f) {
for (int i=0;i<N;i++) if (rev[i]>i) swap(t[i],t[rev[i]]);
for (int i=1;i<N;i<<=1) {
for (int j=0;j<i;j++) { //此处一定要预处理,递推精度感人T_T
E tmp(cos(Pi*f*j/i),f*sin(Pi*j/i));
w[j]=tmp;
}
for (int p=i<<1,j=0;j<N;j+=p) {
for (int k=0;k<i;k++) {
E x=t[k+j],y=t[k+j+i]*w[k];
t[k+j]=x+y;t[k+j+i]=x-y;
}
}
}
}
void FFT(LL *u,LL *v,LL p) {
E clean(0,0);
for (int i=0;i<N;i++) a[i]=b[i]=c[i]=d[i]=A[i]=B[i]=C[i]=clean;
for (int i=0;i<=K;i++) {
F[i]=u[i]*fac[K-i]%MOD*power(p,i)%MOD;
G[i]=v[i]*fac[K-i]%MOD;
}
for (int i=0;i<N;i++) {
a[i]=F[i]>>15;b[i]=F[i]&(M-1);
c[i]=G[i]>>15;d[i]=G[i]&(M-1);
}
DFT(a,1);DFT(b,1);DFT(c,1);DFT(d,1);
for (int i=0;i<N;i++) {
A[i]=a[i]*c[i];
B[i]=a[i]*d[i]+b[i]*c[i];
C[i]=b[i]*d[i];
}
DFT(A,-1);DFT(B,-1);DFT(C,-1);
for (int i=0;i<=K;i++) {
LL X=(LL)(A[i].real()/N+0.5)%MOD;
LL Y=(LL)(B[i].real()/N+0.5)%MOD;
LL Z=(LL)(C[i].real()/N+0.5)%MOD;
u[i]=((X<<30)+(Y<<15)+Z)%MOD;
}
for (int i=0;i<=K;i++) u[i]=u[i]*ifac[K]%MOD*ifac[K-i]%MOD;
} int main() {
scanf("%lld%lld",&n,&K);
if (n>K) {puts("0");return 0;}
for (N=1,L=-1;N<=2*K;N<<=1) L++;
for (int i=0;i<N;i++) rev[i]=(rev[i>>1]>>1) | ((i&1)<<L);
fac[0]=ifac[0]=1;
for (LL i=1;i<=K;i++) {
fac[i]=fac[i-1]*i%MOD;
ifac[i]=power(fac[i],MOD-2);
}
g[0]=1;
for (LL x=1,i=1;i<=K;i++) {
x=x*(K-i+1)%MOD*power(i,MOD-2)%MOD;
f[i]=x;
}
LL p=2;
while (n) {
if (n&1) FFT(g,f,p);
n>>=1;FFT(f,f,p);
p=p*p%MOD;
}
LL res=0;
for (int i=0;i<=K;i++) res=(res+g[i])%MOD;
printf("%lld",res);
return 0;
}

  

【codeforces 623E】 Transforming Sequence的更多相关文章

  1. 【codeforces 466D】Increase Sequence

    [题目链接]:http://codeforces.com/problemset/problem/466/D [题意] 给你n个数字; 让你选择若干个区间; 且这些区间[li,ri]; 左端点不能一样; ...

  2. 【codeforces 602D】Lipshitz Sequence

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  3. 【CodeForces 622A】Infinite Sequence

    题意 一个序列是, 1, 2, 1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4, 5....这样排的,求第n个是什么数字. 分析 第n个位置属于1到k,求出k,然后n-i*(i-1)/ ...

  4. 【codeforces 623E】dp+FFT+快速幂

    题目大意:用$[1,2^k-1]$之间的证书构造一个长度为$n$的序列$a_i$,令$b_i=a_1\ or\ a_2\ or\ ...\ or a_i$,问使得b序列严格递增的方案数,答案对$10^ ...

  5. 【codeforces 415D】Mashmokh and ACM(普通dp)

    [codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...

  6. 【47.40%】【codeforces 743B】Chloe and the sequence

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  7. 【codeforces 438D】The Child and Sequence

    [原题题面]传送门 [大致题意] 给定一个长度为n的非负整数序列a,你需要支持以下操作: 1:给定l,r,输出a[l]+a[l+1]+…+a[r]. 2:给定l,r,x,将a[l],a[l+1],…, ...

  8. 【25.00%】【codeforces 584E】Anton and Ira

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  9. 【66.47%】【codeforces 556B】Case of Fake Numbers

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

随机推荐

  1. 20155209林虹宇 Exp6 信息搜集与漏洞扫描

    Exp6 信息搜集与漏洞扫描 1.信息收集 1.1通过DNS和IP挖掘目标网站的信息 whois查询 进行whois查询时去掉www等前缀,因为注册域名时通常会注册一个上层域名,子域名由自身的域名服务 ...

  2. C#基础之.NET环境下WebConfig的加密

    在将ASP.NET项目部署到服务器上时,内网环境下Web.Config往往是直接复制过去.对于外网环境,则需要对Web.Config文件进行加密. .NET环境下一共提供了2种方式的加密功能,分别是D ...

  3. WordPress留言本插件推荐

    WordPress不借助于任何插件也可以做个留言本,那就是建个 Page, 直接使用它的评论功能即可,而且给评论加上 Ajax 功能.WYSIWYG.引用.回复.留言分页等功能也可以做的很漂亮.但对于 ...

  4. Selenium-ActionChainsApi接口详解

    ActionChains 有时候我们在通过Selenium做UI自动化的时候,明明能够在DOM树内看到这个元素,但是我在通过driver click.sendkey的时候,就是点击不到或无法输入字符串 ...

  5. UWP简单示例(一):快速合成音乐MV

    说明 本文发布时间较早,内容可能已过时.最新动态请关注 TypeScript 版本.(2019 年 3 月 注) 在线演示: 音频可视化(TypeScript) 准备 IDE:Visual Studi ...

  6. Sterling B2B Integrator与SAP交互 - 02 安装配置

    系统组成: 1. 服务器OS及硬件: OS: Red Hat Enterprise Linux Server release 6.6 Hardware: Virtual Machine, x86_64 ...

  7. 云服务器+tomcat+mysql+web项目搭建部署

    云服务器+tomcat+mysql+web项目搭建部署 1.老样子,开头墨迹两句. 作为我的第二篇文章,有很多感慨,第一篇人气好低啊,有点小丧气,不过相信我还是经验少,分享的都是浅显的,所以大家可能不 ...

  8. (1) English Learning

    1.  no-brainer 不必花脑筋的事物 This tool is really no-brainer that almost everyone can use it. 这个工具太简单用了,不会 ...

  9. Netty源码分析(前言, 概述及目录)

    Netty源码分析(完整版) 前言 前段时间公司准备改造redis的客户端, 原生的客户端是阻塞式链接, 并且链接池初始化的链接数并不高, 高并发场景会有获取不到连接的尴尬, 所以考虑了用netty长 ...

  10. unity上传app store遇到的一些问题

    记录ios发布时遇到的一些问题 注:如果你是用mac开发,那就在Unity里直接BuildAndRun就直接可以导到XCode里,如果是win,那就先打包成ios包,在传导Xcode里打开,不过可能会 ...