题面:

看无可看(see.pas/cpp/c)

题目描述

“What’s left to see when our eyes won’t open?”

“若彼此瞑目在即,是否终亦看无可看?”

------来自网易云音乐<Golden Leaves-Passenger>

最后的一刻我看到了......

一片昏暗?

我记起来了,

我看到,那里有一个集合S,集合S中有n个正整数a[i](1<=i<=n)

我看到,打破昏暗的密码:

记忆中的f是一个数列,对于i>1它满足f(i)=2*f(i-1)+3*f(i-2)

给出n,k,f(0),f(1)和a[i],求上述式子的值,由于答案很大,输出答案对99991取模的结果即可

输入

第一行两个正整数n和k

第二行n个正整数a[i],1<=a[i]<=10^9

第三行两个正整数f(0)和f(1),1<=f0,f1<99991

输出

一行一个数表示式子的值对99991取模的结果,详情见题目描述

样例输入1

4 2

1 2 1 3

1 1

样例输出1

234

样例输入2

20 10

125 3162 3261 152 376 238 462 4382 376 4972 16 1872 463 9878 688 308 125 236 3526 543

1223 3412

样例输出2

32071

样例输入3、4

见下发文件

样例输出3、4

见下发文件

样例1解释

f={1,1,5,13,41,121,365,1093,3281,9841...}

选a[1]和a[2],则f(a[1]+a[2])=13

选a[1]和a[3],则f(a[1]+a[3])=5

选a[1]和a[4],则f(a[1]+a[4])=41

选a[2]和a[3],则f(a[2]+a[3])=13

选a[2]和a[4],则f(a[2]+a[4])=121

选a[3]和a[4],则f(a[3]+a[4])=41

则ans=13+5+41+13+121+41=234

数据范围

对于20%的数据,1<=n<=20

对于另外10%的数据满足f(0)=f(1)=1

对于另外20%的数据满足1<=n<=5000

对于另外20%的数据满足所有a[i]的和<=10000,1<=n<=100

对于100%的数据,1<=n<=100000,1<=a[i]<=10^9,1<=f[0],f[1]<99991

思路:

先特征值方程搞出来f的通项

是K*3^n+B*(-1)^n

带入f[0],f[1]解出来k和B

观察式子

发现后面一项只跟a[i]和的奇偶性有关

枚举选了多少个奇数的 组合数搞一搞

前一项可以分治FFT

看成(1+3^a[i])(1+3^a[i])一堆乘一块

解题报告:

see

关键字:常系数齐次线性递推,分治,FFT

对于20%的数据,1<=n<=20”

直接暴力就好了。

对于另外10%的数据满足f(0)=f(1)=1”

这档是给OEIS和找到某种神奇规律的选手的,然而我不会

对于另外20%的数据满足所有a[i]的和<=1000,1<=n<=100”

DP,设f[i][j][x]表示前i个数里面选了j个和为x的方案数,直接算。

对于另外20%的数据满足1<=n<=5000”

f(i)=2*f(i-1)+3*f(i-2)

显然f是一个常系数齐次线性递推的形式,考虑求第n项大概是这样一个过程:

首先,求出x^n对M(x)=x^2-2*x-3取模的结果,设为Res(n)=k[n]*x+b[n](注:Res(n)为多项式)

然后f(n)即为k[n]*f[1]+b[n]*f[0]

考虑计算f[a+c]+f[b+c]

即求出Res(a+c)+Res(b+c)

那么由于Res(a+c)=Res(a)*Res(c)    (MOD  M(x))

得到Res(a+c)+Res(b+c)=(Res(a)+Res(b))*Res(c)  (MOD M(x))

得到这个结论后我们可以有一个O(n^2)的DP:

设f[i][j]表示前i个数里面选了j个的所有方案的Res的和,也就是说f[i][j]是一个一次多项式,那么转移就是g[i][j]=g[i-1][j]+g[i-1][j-1]*Res(a[i])  (MOD M(x))

最后利用g[n][k]得到答案

进阶满分

上面比较麻烦的是有一个一次多项式,那么如何去掉这个一次多项式的影响呢?

考虑ax+b和cx+d对M(x)取模的答案

(ax+b)*(cx+d)=(ad+bc+2ac)x+(bd+3ac)  (MOD M(x))

于是定义一类新的数,称之为One-Degree Number(当然这是我瞎起的名字,下文称之为ODN)

定义ODN t=(a,b)表示t=ax+b,定义乘法(a,b)*(c,d)=(ad+bc+2ac,bd+3ac),加法与减法显然(没有必要使用除法所以不讨论ODN的除法)

那么Res(a[i])也可以看做是一个ODN

设Gi(y)表示g[i][j]的生成函数,那么Gi(y)=Gi-1(y)*(1+Res(a[i])*y)

这个像什么?分治FFT!!!

如果我们可以做ODN的FFT,那么我们就可以利用分治FFT算出Gn(y),利用其第k项算出答案。

怎么做ODN的FFT?

这个不是传统的实数,但是有一个东西是和实数域相同的,单位元都是1!!

这就说明我们可以直接用主n次单位复数根来进行运算,即使进行FFT的数是ODN!!

但是要注意的是进行FFT时要重定义数的类型,详情见标程。

时间复杂度O(n (log n)^2)

其实本题可以用二维的FFT来实现,而常系数线性递推的式子也可以不止 2

代码:

//By SiriusRen
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double pi=acos(-);
const int N=,Base=,mod=;
int n,k,fsta[N],O1,O2,inv[N],fac[N],K,B,R[N],jyx,jyy,f[N],ta[N],tb[N],tc[N],len;
int power(int x,int y){
int r=;
while(y){
if(y&)r=1ll*r*x%mod;
x=1ll*x*x%mod,y>>=;
}return r;
}
struct Complex{
double x,y;Complex(){}
Complex (double X,double Y){x=X,y=Y;}
}a1[N],a2[N],b1[N],b2[N],c1[N],c2[N],c3[N];
Complex operator+(Complex a,Complex b){return Complex(a.x+b.x,a.y+b.y);}
Complex operator-(Complex a,Complex b){return Complex(a.x-b.x,a.y-b.y);}
Complex operator*(Complex a,Complex b){return Complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
Complex operator/(Complex a,int b){return Complex(a.x/b,a.y/b);}
void FFT(Complex *a,int f){
for(int i=;i<len;i++)if(i<R[i])swap(a[i],a[R[i]]);
for(int l=;l<len;l<<=){
Complex wn=Complex(cos(pi/l),f*sin(pi/l));
for(int j=;j<len;j+=(l<<)){
Complex w=Complex(,);
for(int k=;k<l;k++,w=w*wn){
Complex X=a[j+k],Y=w*a[j+k+l];
a[j+k]=X+Y,a[j+k+l]=X-Y;
}
}
}
if(f==-)for(int i=;i<len;i++)a[i]=a[i]/len;
}
void mul(int *X,int *Y,int *Z){
for(int i=;i<len;i++){
a1[i].y=a2[i].y=b1[i].y=b2[i].y=;
a1[i].x=X[i]/Base,a2[i].x=X[i]%Base;
b1[i].x=Y[i]/Base,b2[i].x=Y[i]%Base;
}
FFT(a1,),FFT(a2,),FFT(b1,),FFT(b2,);
for(int i=;i<len;i++){
c1[i]=a1[i]*b1[i];
c2[i]=(a1[i]*b2[i]+a2[i]*b1[i]);
c3[i]=a2[i]*b2[i];
}FFT(c1,-),FFT(c2,-),FFT(c3,-);
for(int i=;i<len;i++){
ll temp=((ll)(c1[i].x+0.3)%mod*Base%mod*Base%mod+(ll)(c2[i].x+0.3)%mod*Base%mod+(ll)(c3[i].x+0.3)%mod)%mod;
Z[i]=temp;
}
}
int C(int x,int y){
if(x<y)return ;
return 1ll*fac[x]*inv[x-y]%mod*inv[y]%mod;
}
void cdq(int l,int r){
if(l==r){
f[l*-]=,f[l*]=1ll*power(,fsta[l])%mod;
return;
}
int mid=(l+r)>>;
cdq(l,mid),cdq(mid+,r);
int len1=(mid-l+)*,len2=(r-mid)*,L=;len=;
while(len<=len1+len2)len<<=,L++;
for(int i=;i<len;i++)R[i]=(R[i>>]>>)|((i&)<<(L-));
for(int i=;i<len1;i++)ta[i]=f[l*-+i];
for(int i=len1;i<len;i++)ta[i]=;
for(int i=;i<len;i++)tb[i]=f[mid*++i];
mul(ta,tb,tc);
for(int i=;i<len1+len2;i++)f[l*-+i]=tc[i];
}
int main(){
freopen("see.in","r",stdin);
freopen("see.out","w",stdout);
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++){
scanf("%d",&fsta[i]);
fsta[i]=fsta[i]%;
if(fsta[i]&)O1++;
else O2++;
}
scanf("%d%d",&jyx,&jyy);
inv[]=inv[]=fac[]=;
for(int i=;i<mod;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(int i=;i<mod;i++)fac[i]=1ll*fac[i-]*i%mod;
K=1ll*(jyx+jyy)*inv[]%mod,B=(jyx-K+mod)%mod;
for(int i=;i<mod;i++)inv[i]=1ll*inv[i]*inv[i-]%mod;
int ans=;
for(int i=;i<=k;i++)
ans=(ans+((i&)?-1ll:1ll)*C(O1,i)*C(O2,k-i)%mod%mod)%mod;
cdq(,n);
printf("%lld\n",((1ll*f[k+]*K%mod+1ll*B*ans)%mod+mod)%mod);
}

看无可看 分治FFT+特征值方程的更多相关文章

  1. Loj#6183. 看无可看

    Loj#6183. 看无可看 题目描述 首先用特征根求出通项公式\(A_n=p\cdot 3^n+q\cdot(-1)^n\).通过给定的\(f_0,f_1\)可以解出\(p,q\). 然后我们要求的 ...

  2. [Contest20180415]看无可看

    题意:有一个数列$f$,对$\forall i\geq2,f_i=2f_{i-1}+3f_{i-2}$,给定$f_0,f_1$,再给定一个集合$S=\{a_{1\cdots n}\}$和$k$,求$\ ...

  3. 「6月雅礼集训 2017 Day1」看无可看

    [题目大意] 给出n个数,a[1]...a[n],称作集合S,求

  4. 洛谷P4721 【模板】分治 FFT(生成函数+多项式求逆)

    传送门 我是用多项式求逆做的因为分治FFT看不懂…… upd:分治FFT的看这里 话说这个万恶的生成函数到底是什么东西…… 我们令$F(x)=\sum_{i=0}^\infty f_ix^i,G(x) ...

  5. HDU - 5307 :He is Flying (分治+FFT)(非正解)

    JRY wants to drag racing along a long road. There are nn sections on the road, the ii-th section has ...

  6. BNUOJ 51279[组队活动 Large](cdq分治+FFT)

    传送门 大意:ACM校队一共有n名队员,从1到n标号,现在n名队员要组成若干支队伍,每支队伍至多有m名队员,求一共有多少种不同的组队方案.两个组队方案被视为不同的,当且仅当存在至少一名队员在两种方案中 ...

  7. BZOJ 4555: [Tjoi2016&Heoi2016]求和 [分治FFT 组合计数 | 多项式求逆]

    4555: [Tjoi2016&Heoi2016]求和 题意:求\[ \sum_{i=0}^n \sum_{j=0}^i S(i,j)\cdot 2^j\cdot j! \\ S是第二类斯特林 ...

  8. 分治FFT的三种含义

    分治FFT是几个算法的统称.它们之间并无关联. 分治多项式乘法 问题如求\(\prod_{i=1}^na_ix+b\). 若挨个乘复杂度为\(O(n^2\log n)\),可分治做这件事,复杂度为\( ...

  9. HDU.5730.Shell Necklace(分治FFT)

    题目链接 \(Description\) 有\(n\)个长度分别为\(1,2,\ldots,n\)的珠子串,每个有\(a_i\)种,每种个数不限.求有多少种方法组成长度为\(n\)的串.答案对\(31 ...

随机推荐

  1. 关于app.js和route.js和service.js还有controller.js中的依赖关系

    2.只要是由路由去执行的的控制器模块,必须注入到app.js里面进行依赖,在页面上就不需要ng-controller在html页面上写了:   但是如果一个控制器模块,没有经过路由管理:那么就必须要, ...

  2. JavaScript保留关键字(全)

    JavaScript 标准 所有的现代浏览器已经完全支持 ES5(ECMAScript 5). JavaScript 保留关键字(keyword) Javascript 的保留关键字(标识符)不可以用 ...

  3. [luoguP2701] [USACO5.3]巨大的牛棚Big Barn(DP)

    传送门 经典问题. 找出最大的不包含 1 的正方形. f[i][j] 表示 以 (i,j) 结尾的最大的不包含 1 的正方形 f[i][j] = min(f[i - 1][j], f[i][j - 1 ...

  4. 从一行代码开始,浅谈python字符串格式化

    今天看到了一行这样的代码: boundary = '%.32x' % random.randint(0, 256**16) 我知道这是一个生成格式化字符串的语句,它将随机生成的一个32位16进制数,将 ...

  5. [K/3Cloud]如何解决kdpkg无法部署到业务站点的问题

    自从下载了sp1后,就迫不急待的试用下,看看反馈的几个关键bug是否修复,可惜sp1安装后发现业务站点下的组件一个都没有被更新,这指定是有问题了,这真是让哥百思不得其解,真后悔在研发时没仔细研究下部署 ...

  6. 布局(codevs 1242)

    题目描述 Description 当排队等候喂食时,奶牛喜欢和它们的朋友站得靠近些.FJ有N(2<=N<=1000)头奶牛,编号从1到N,沿一条直线站着等候喂食.奶牛排在队伍中的顺序和它们 ...

  7. 在Myeclipse中拷贝一个web项目,但是tomcat文件夹中没有更新,需要进行修改才能更新。

    1.在Myeclipse中拷贝一个web项目,但是tocat文件夹中没有更新,需要进行修改才能更新. 2.方法:右键这个工程,然后Properties->MyEclipse->Projec ...

  8. codevs1005 生日礼物

    题目描述 Description 9月12日是小松的朋友小寒的生日.小松知道小寒特别喜欢蝴蝶,所以决定折蝴蝶作为给小寒的生日礼物.他来到了PK大学最大的一家地下超市,在超市里,小松找到了n种可以用来折 ...

  9. 单例模式解决RabbitMQ超出最大连接问题

    今天在项目稳定性测试过程中遇到一个情景:通过工具jMeter一直请求消息转发服务器,消息转发服务器再向rabbitMQ发送数据,在这期间出现了问题.MQ意外宕机. 1. 查看rabbitMQ管理界面. ...

  10. [BZOJ1096][ZJOI2007]仓库建设(斜率优化DP)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1096 分析: 假设1~10,如果在3 6 10建立仓库,那么当前建立仓库决策下的最优值 ...