这个题简直有毒,\(O((a+b)^3logn)\)的做法不卡常只比\(O(2^n*n)\)多\(10\)分

看到\(a\)和\(b\)简直小的可怜,于是可以往矩阵上联想

发现这个柿子有些特殊,好像可以二项式定理搞一搞

于是\(x^ay^b\)可以写成\((n-y)^ay^b\)

于是接下来就二项式定理好了

\[(n-y)^ay^b=\sum_{r=0}^a\binom{a}{r}n^{a-r}*(-y)^r*y^b
\]

\[=\sum_{r=0}^a\binom{a}{r}n^{a-r}*(-1)^r*y^{b+r}
\]

发现好像可以用矩阵来维护这个\(\sum\)的每一项

先列一下\(dp\)的方程,设\(dp[i][j][0/1]\)表示进行到第\(i\)位上,这个\(\sum\)的第\(j\)次方项,最后一位填的是\(0/1\)

如果这一位填\(0\),对答案并没有什么贡献,但是前面填\(0/1\)都是可以的,于是\(dp[i][j][0]=dp[i-1][j][0]+dp[i-1][j][1]\)

如果这一位填的是\(1\),那么前面的那一位只能填\(0\),\(y\)增加了\(1\),所以答案变成了\((y+1)^j\)

还是用二项式定理

\[(y+1)^j=\sum_{k=0}^j\binom{j}{k}y^k
\]

所以也就可以得到

\[dp[i][j][1]=\sum_{k=0}^j\binom{j}{k}*dp[i-1][k][0]
\]

矩阵维护就可以了

#include<iostream>
#include<cstring>
#include<cstdio>
#define re register
#define maxn 185
#define LL long long
LL a[maxn][maxn],ans[maxn][maxn];
int sz;
int T,A,b,P;
LL c[maxn][maxn];
inline void did_a()
{
LL mid[maxn][maxn];
for(re int i=1;i<=sz;i++)
for(re int j=1;j<=sz;j++)
mid[i][j]=a[i][j],a[i][j]=0;
for(re int i=1;i<=sz;i++)
for(re int k=1;k<=sz;k++)
for(re int j=1;j<=sz;j++)
{
a[i][j]+=mid[i][k]*mid[k][j];
if(a[i][j]>P) a[i][j]%=P;
}
}
inline void did_ans()
{
LL mid[maxn][maxn];
for(re int i=1;i<=sz;i++)
for(re int j=1;j<=sz;j++)
mid[i][j]=ans[i][j],ans[i][j]=0;
for(re int i=1;i<=sz;i++)
for(re int k=1;k<=sz;k++)
for(re int j=1;j<=sz;j++)
{
ans[i][j]+=mid[i][k]*a[k][j];
if(ans[i][j]>P) ans[i][j]%=P;
}
}
inline LL quick(LL a,int b)
{
LL S=1;
while(b)
{
if(b&1) S=S*a%P;
b>>=1;
a=a*a%P;
}
return S;
}
inline void Mat_quick(int b)
{
while(b)
{
if(b&1) did_ans();
b>>=1;
did_a();
}
}
int main()
{
scanf("%d%d%d%d",&T,&A,&b,&P);
c[0][0]=1;
for(re int i=1;i<=A+b;i++) c[i][0]=c[i][i]=1;
for(re int i=1;i<=A+b;i++)
for(re int j=1;j<i;j++)
c[i][j]=(c[i-1][j-1]+c[i-1][j])%P;
sz=(A+b+1)*2;
for(re int i=1;i<=sz;i++)
ans[i][i]=1;
for(re int i=1;i<=(sz>>1);i++)
a[i][i]=a[i+sz/2][i]=1;
for(re int i=1;i<=(sz>>1);i++)
for(re int j=i+sz/2;j<=sz;j++)
a[i][j]=c[j-1-sz/2][i-1];
Mat_quick(T);
LL Ans=0;
for(re int i=0;i<=A;i++)
if(i&1) Ans=(Ans-c[A][i]*quick(T,A-i)%P*(ans[1][i+1+b]+ans[1][i+1+b+sz/2]%P)%P+P)%P;
else Ans=(Ans+c[A][i]*quick(T,A-i)%P*(ans[1][i+1+b]+ans[1][i+1+b+sz/2]%P))%P;
std::cout<<Ans;
return 0;
}

【[CQOI2018]交错序列】的更多相关文章

  1. 【BZOJ5298】[CQOI2018]交错序列(动态规划,矩阵快速幂)

    [BZOJ5298][CQOI2018]交错序列(动态规划,矩阵快速幂) 题面 BZOJ 洛谷 题解 考虑由\(x\)个\(1\)和\(y\)个\(0\)组成的合法串的个数. 显然就是把\(1\)当做 ...

  2. [CQOI2018]交错序列 (矩阵快速幂,数论)

    [CQOI2018]交错序列 \(solution:\) 这一题出得真的很好,将原本一道矩阵快速幂硬生生加入组合数的标签,还那么没有违和感,那么让人看不出来.所以做这道题必须先知道(矩阵快速幂及如何构 ...

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

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

  4. [CQOI2018]交错序列

    嘟嘟嘟 要是求交错序列的个数和就好了,那我一秒就能切. 换成这个,我就不会了. 我一直想枚举1的个数,然后算出在长度为\(n\)的序列里,有多少个合法的序列,然后又觉得这好像是什么插板法,但是每一个盒 ...

  5. bzoj 5298: [Cqoi2018]交错序列

    Description 我们称一个仅由0.1构成的序列为"交错序列",当且仅当序列中没有相邻的1(可以有相邻的0).例如,000,001 ,101,都是交错序列,而110则不是.对 ...

  6. BZOJ5298 [CQOI2018] 交错序列 | 矩阵乘法和一个trick

    题面 求所有长度为\(n\)的.没有相邻的1的01序列中,若0有\(x\)个.1有\(y\)个,\(x^ay^b\)之和(对\(m\)取模). \(n \le 10^7, m \le 10^8, 0 ...

  7. BZOJ5298 CQOI2018交错序列(动态规划+矩阵快速幂)

    显然答案为Σkb·(n-k)a·C(n-k+1,k).并且可以发现ΣC(n-k,k)=fibn.但这实际上没有任何卵用. 纯组合看起来不太行得通,换个思路,考虑一个显然的dp,即设f[i][j][0/ ...

  8. [BZOJ5298][CQOI2018]交错序列(DP+矩阵乘法)

    https://blog.csdn.net/dream_maker_yk/article/details/80377490 斯特林数有时并没有用. #include<cstdio> #in ...

  9. cqoi2018

    题解: 很多模板题 第一次写莫队还比较顺利 除了把排序的cmp写错..(还第一次遇到) 这题分块也可以 先预处理出g[i][j]代表前i个块,颜色为j的有多少种 f[i][j]表示i-j的块能构成多少 ...

随机推荐

  1. 使用MUI框架,模拟手机端的下拉刷新,上拉加载操作。

    套用mui官方文档的一句话:“开发者只需关心业务逻辑,实现加载更多数据即可”.真的是不错的框架. 想更多的了解这个框架:http://dev.dcloud.net.cn/mui/ 那么如何实现下拉刷新 ...

  2. [编程] C语言枚举类型(Enum)

    C语言枚举类型(Enum):定义形式为:enum typeName{ valueName1, valueName2, valueName3, ...... };enum 类型名{名字1,名字2} 枚举 ...

  3. 关于JAVA是值传递还是引用传递的问题

    1.概念 值传递:方法调用时,实际传入的是它的副本,在方法中对值的修改,不影响调用者的值. 引用传递:方法调用时,实际传入的是参数的实际内存地址,调用者和调用方法所操作的参数都指向同一内存地址,所以方 ...

  4. Source not found ( Eclipse 关联源代码)

    一.问题 有时候我们在查看源码时提示没有找到, 这时就需要我们手动关联源码 二.关联 首先需要根据提示下载对应的源代码文件 选择我们下载好的源码 三.修改/删除关联 如果需要重新切换源码 四.参考 j ...

  5. 【Java】短信信息提取设计

    问题产生:当有要求做信息有效性校验的时候,如何提取短信中有用的信息? 举个例子:有这样一条短信消息: [XXXXXX提醒]尊敬的客户,截止03月21日15:29,您本月套餐中包含手机上网国内流量累计1 ...

  6. JS获取今天年月日

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. python用random产生验证码,以及random的一些其他用法

    产生随机验证码函数 import random def get_code(): code = '' for i in range(5): num = str(random.randrange(10)) ...

  8. jQuery轮播图(二)利用构造函数和原型创建对象以实现继承

    本文是在我开始学习JavaScript继承时,对原型继承的一些理解和运用.文中所述的继承方式均是使用js特有的原型链方式,实际上有了ES6的类之后,实现继承的就变得十分简单了,所以这种写法现在也不在推 ...

  9. 初级篇html。

    什么是html?  超文本标记语言,标准通用标记语言下的一个应用. “超文本”就是指页面内可以包含图片.链接,甚至音乐.程序等非文字元素. 超文本标记语言的结构包括“头”部分(英语:Head).和“主 ...

  10. 爬虫必备—BeautifulSoup

    BeautifulSoup是一个模块,该模块用于接收一个HTML或XML字符串,然后将其进行格式化,之后便可以使用他提供的方法进行快速查找指定元素,从而使得在HTML或XML中查找指定元素变得简单. ...