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

数据范围,$n≤10^{18}$,$k≤30000$。

考虑用dp来解决这一题,我们用$f[i][j]$来表示前$i$个数中,使用了$j$个二进制位(注意!并不是前$j$个),那么答案显然为$\sum_{i=0}^{k} \binom{n}{i} \times f[n][i]$。

考虑如何用前面求得的数值来更新$f[x+y][i]$,不妨设$j∈[1,i]$。

不难推出,用了$x$个数,在$i$个二进制位中选用了$j$个二进制位的方案数为$\binom{i}{j} \times f[x][j]$。

然后,用掉$y$个数,并选用余下$i-j$个二进制位的方案数为$f[y][i-j]$。

考虑到前面$x$个数已经选择了$j$个二进制位,那么剩下的$y$个数,在这$j$个位置上,均可以随便填0或1,方案数为$(2^j)^y$。

通过上文分析,得$f[x+y][i]=\sum_{j=1}^{i} f[x][j] \times \binom{i}{j} \times f[y][i-j] \times (2^j)^y$。

通过简单整理,$=i!\sum_{j=1}^{i} \frac{f[x][j]\times (2^j)^y}{j!} \times \frac{f[y][i-j]}{(i-j)!}$。

然后,我们就可以通过NTT,进行dp式子的转移。

不过此题的模数非常恶心,所以需要用任意模数FFT。

考虑到$n$范围非常大,所以$x$和$y$的选择必须要有技巧,我们可以用类似快速幂的算法,加速转移,详情可见代码。

时间复杂度为$O(k\ log\ k\ log\ n)$。

 #include<bits/stdc++.h>
#define L long long
#define MOD 1000000007
#define H 16
#define M 1<<H
#define hh 32768
#define PI acos(-1)
using namespace std;
int nn;
int k; L n; L pow_mod(L x,L k){
L ans=;
while(k){
if(k&) ans=ans*x%MOD;
k>>=; x=x*x%MOD;
}
return ans;
} struct cp{
double i,r;
cp(){i=r=;}
cp(double rr,double ii){i=ii; r=rr;}
friend cp operator +(cp a,cp b){return cp(a.r+b.r,a.i+b.i);}
friend cp operator -(cp a,cp b){return cp(a.r-b.r,a.i-b.i);}
friend cp operator *(cp a,cp b){return cp(a.r*b.r-a.i*b.i,a.r*b.i+a.i*b.r);}
L D(){L hhh=(r+0.499); return hhh%MOD;}
}; cp w[M][H];
void init(){
for(int i=,j=;j<H;j++,i<<=){
for(int k=;k<i;k++)
w[k][j]=cp(cos(*PI*k/i),sin(*PI*k/i));
}
} void change(cp a[],int n){
for(int i=,j=;i<n-;i++){
if(i<j) swap(a[i],a[j]);
int k=n>>;
while(j>=k) j-=k,k>>=;
j+=k;
}
}
void FFT(cp a[],int n,int on){
change(a,n);
cp wn,u,t;
for(int h=,i=;h<=n;h<<=,i++){
for(int j=;j<n;j+=h){
for(int k=j;k<j+(h>>);k++){
wn=w[k-j][i]; if(on==-) wn.i=-wn.i;
u=a[k]; t=a[k+(h>>)]*wn;
a[k]=u+t; a[k+(h>>)]=u-t;
}
}
}
if(on==-)
for(int i=;i<n;i++) a[i].r=a[i].r/n;
} struct poly{
L a[M];
poly(){memset(a,,sizeof(a));}
friend poly operator *(poly a,poly b){
poly c;
static cp A[M],B[M],C[M],D[M],E[M],F[M],G[M];
memset(A,,sizeof(A)); memset(B,,sizeof(B));
memset(C,,sizeof(C)); memset(D,,sizeof(D));
for(int i=;i<nn;i++) A[i].r=a.a[i]%hh,B[i].r=a.a[i]/hh;
for(int i=;i<nn;i++) C[i].r=b.a[i]%hh,D[i].r=b.a[i]/hh;
FFT(A,nn,); FFT(B,nn,); FFT(C,nn,); FFT(D,nn,);
for(int i=;i<nn;i++){
E[i]=A[i]*C[i];
F[i]=A[i]*D[i]+B[i]*C[i];
G[i]=B[i]*D[i];
}
FFT(E,nn,-); FFT(F,nn,-); FFT(G,nn,-);
for(int i=;i<nn;i++)
c.a[i]=(E[i].D()+F[i].D()*hh%MOD+G[i].D()*hh%MOD*hh%MOD)%MOD;
for(int i=k+;i<nn;i++) c.a[i]=;
return c;
}
};
L fac[M]={},invfac[M]={};
L C(int n,int m){return fac[n]*invfac[m]%MOD*invfac[n-m]%MOD;}
poly ans,f,f1,f2;
int main(){
init();
cin>>n>>k; n--;
fac[]=; for(int i=;i<=k;i++) fac[i]=fac[i-]*i%MOD;
invfac[k]=pow_mod(fac[k],MOD-);
for(int i=k-;~i;i--) invfac[i]=invfac[i+]*(i+)%MOD;
for(nn=;nn<=(k*);nn<<=);
L now=;
for(int i=;i<=k;i++) f.a[i]=;
ans=f;
while(n){
if(n&){
f1=ans; f2=f;
for(int i=;i<=k;i++)
f1.a[i]=f1.a[i]*invfac[i]%MOD*pow_mod(pow_mod(,i),now)%MOD;
for(int i=;i<=k;i++)
f2.a[i]=f2.a[i]*invfac[i]%MOD;
ans=f1*f2;
for(int i=;i<=k;i++)
ans.a[i]=ans.a[i]*fac[i]%MOD;
}
f1=f; f2=f;
for(int i=;i<=k;i++)
f1.a[i]=f1.a[i]*invfac[i]%MOD*pow_mod(pow_mod(,i),now)%MOD;
for(int i=;i<=k;i++)
f2.a[i]=f2.a[i]*invfac[i]%MOD;
f=f1*f2;
for(int i=;i<=k;i++)
f.a[i]=f.a[i]*fac[i]%MOD;
n>>=; now<<=;
}
L sum=;
for(int i=;i<=k;i++)
sum=(sum+ans.a[i]*C(k,i))%MOD;
cout<<sum<<endl;
}

【codeforces 623E】dp+FFT+快速幂的更多相关文章

  1. codeforces E. Okabe and El Psy Kongroo(dp+矩阵快速幂)

    题目链接:http://codeforces.com/contest/821/problem/E 题意:我们现在位于(0,0)处,目标是走到(K,0)处.每一次我们都可以从(x,y)走到(x+1,y- ...

  2. Codeforces 621E Wet Shark and Block【dp + 矩阵快速幂】

    题意: 有b个blocks,每个blocks都有n个相同的0~9的数字,如果从第一个block选1,从第二个block选2,那么就构成12,问对于给定的n,b有多少种构成方案使最后模x的余数为k. 分 ...

  3. bnuoj 34985 Elegant String DP+矩阵快速幂

    题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985 We define a kind of strings as elegant s ...

  4. HDU 5434 Peace small elephant 状压dp+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant  Accepts: 38  Submissions: ...

  5. 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂

    [题意]n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n ...

  6. 【BZOJ】4861: [Beijing2017]魔法咒语 AC自动机+DP+矩阵快速幂

    [题意]给定n个原串和m个禁忌串,要求用原串集合能拼出的不含禁忌串且长度为L的串的数量.(60%)n,m<=50,L<=100.(40%)原串长度为1或2,L<=10^18. [算法 ...

  7. BZOJ5298 CQOI2018 交错序列 【DP+矩阵快速幂优化】*

    BZOJ5298 CQOI2018 交错序列 [DP+矩阵快速幂优化] Description 我们称一个仅由0.1构成的序列为"交错序列",当且仅当序列中没有相邻的1(可以有相邻 ...

  8. CodeForces 185A. Plant (矩阵快速幂)

    CodeForces 185A. Plant (矩阵快速幂) 题意分析 求解N年后,向上的三角形和向下的三角形的个数分别是多少.如图所示: N=0时只有一个向上的三角形,N=1时有3个向上的三角形,1 ...

  9. BZOJ 3160: 万径人踪灭 FFT+快速幂+manacher

    BZOJ 3160: 万径人踪灭 题目传送门 [题目大意] 给定一个长度为n的01串,求有多少个回文子序列? 回文子序列是指从原串中找出任意个,使得构成一个回文串,并且位置也是沿某一对称轴对称. 假如 ...

随机推荐

  1. 【JAVA】通过URLConnection/HttpURLConnection发送HTTP请求的方法(一)

    Java原生的API可用于发送HTTP请求 即java.net.URL.java.net.URLConnection,JDK自带的类: 1.通过统一资源定位器(java.net.URL)获取连接器(j ...

  2. 2018.08.30 NOIP模拟 wall(模拟)

    [问题描述] 万里长城是中国强大的标志,长城在古代的用途主要用于快速传递军事消息和抵御 外敌,在长城上的烽火台即可以作为藏兵的堡垒有可以来点燃狼烟传递消息. 现在有一段 万里长城,一共有 N 个烽火台 ...

  3. Repository模式中,Update总是失败及其解析(转)

    出处:http://www.cnblogs.com/scy251147/p/3688844.html 关于Entity Framework中的Attached报错的完美解决方案终极版 前发表过一篇文章 ...

  4. 程序员面试50题(1)—查找最小的k个元素[算法]

    题目:输入n个整数,输出其中最小的k个.例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4. 分析:这道题最简单的思路莫过于把输入的n个整数排序,这样排在最前面的k个数 ...

  5. java浅拷贝和深拷贝

    转:http://blog.csdn.net/u014727260/article/details/55003402 实现clone的2点: 1,clone方法是Object类的一个方法,所以任何一个 ...

  6. 7) mvn dependency:tree

    http://maven.apache.org/plugins/maven-dependency-plugin/tree-mojo.html mvn dependency:tree 查看 <de ...

  7. 第二届普适计算和信号处理及应用国际会议论文2016年 The 2nd Conference on Pervasive Computing, Signal Processing and Applications(PCSPA, 2016)

    A New Method for Mutual Coupling Correction of Array Output Signal 一种阵列输出信号互耦校正的新方法 Research of Robu ...

  8. Vivado级联Modelsim仿真Re-launch问题

    前两天在群里看到有朋友说Vivado级联Modelsim仿真出现修改设计代码后重新run do文件,波形没有随着代码修改而改变,这个问题博主之前没有注意到,因为把Vivado和Modelsim级联好后 ...

  9. POJ2676 – Sudoku(数独)—DFS

    Sudoku Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 24081   Accepted: 11242   Specia ...

  10. 深入理解BS结构应用程序

    随着学习的深入,和编程经验的丰富,对BS应用程序有一些认识. 在一些讨论软件技术的QQ群里,或一些社区.BBS中,经常会有一些初学者会犯一些认知性的错误.比如经常会有一些朋友提这样的一些问题:“我怎么 ...