【codeforces 623E】 Transforming Sequence
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的更多相关文章
- 【codeforces 466D】Increase Sequence
[题目链接]:http://codeforces.com/problemset/problem/466/D [题意] 给你n个数字; 让你选择若干个区间; 且这些区间[li,ri]; 左端点不能一样; ...
- 【codeforces 602D】Lipshitz Sequence
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 【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)/ ...
- 【codeforces 623E】dp+FFT+快速幂
题目大意:用$[1,2^k-1]$之间的证书构造一个长度为$n$的序列$a_i$,令$b_i=a_1\ or\ a_2\ or\ ...\ or a_i$,问使得b序列严格递增的方案数,答案对$10^ ...
- 【codeforces 415D】Mashmokh and ACM(普通dp)
[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...
- 【47.40%】【codeforces 743B】Chloe and the sequence
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 【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],…, ...
- 【25.00%】【codeforces 584E】Anton and Ira
time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...
- 【66.47%】【codeforces 556B】Case of Fake Numbers
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
随机推荐
- Eclipse安装Git插件(在线和离线)
在线安装: help-->install new software-->add location就是安装的地址:http://download.eclipse.org/egit/updat ...
- 9.Libraries and visibility 库和可见性
import和liabrary指令可以帮助你创建模块化,可复用的代码.库不仅仅提供API,也是一个私有化单元:库中已下划线(_)开头的类都是对外不可访问的.每个Dart的应用也是一个包,尽管它没有使用 ...
- 20155308『网络对抗技术』Exp5 MSF基础应用
20155308『网络对抗技术』Exp5 MSF基础应用 一.原理与实践说明 实践内容 本实践目标是掌握metasploit的基本应用方式,重点常用的三种攻击方式的思路.具体需要完成: 一个主动攻击实 ...
- 小程序echarts数据不改变,或者是一次渲染成功,第二次进入,渲染失败的解决办法
1.引入echarts插件: import * as echarts from '../../ec-canvas/echarts'; 2.data中定义: ecBar: { onInit: initC ...
- Python基础(字符串和编码)
字符编码 我们已经讲过了,字符串也是一种数据类型,但是,字符串比较特殊的是还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特 ...
- Command and Query Responsibility分离模式
CQRS模式,就是命令和查询责任分离模式. CQRS模式通过使用不同的接口来分离读取数据和更新数据的操作.CQRS模式可以最大化性能,扩展性以及安全性,还会为系统的持续演化提供更多的弹性,防止Upda ...
- C++ 对引用的深入理解
观看了唐老师讲解的一节<第5课 - 引用的本质分析>感觉非常不错,有深度不废话,我喜欢--- 再此总结下,并且奉上视频下载地址--- 360网盘下载地址: https://yunpan.c ...
- 谈谈对Python装饰器的理解
装饰器,又名函数修饰符.笔者觉得函数修饰符,这个名字更能直观的反应他的作用. 函数修饰符语法特征 : @ + 修饰符 函数修饰符的装饰对象: 函数修饰符,就是说他修饰的是 ...
- Js_图片轮播
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- How to export data from Thermo-Calc 如何从Thermo-calc导出文本数据
记录20180510 问题:如何从thermo-calc导出文本数据供origin绘图? 解决: In Thermo-Calc graphical mode, you can just add a ' ...