[CQOI2018]交错序列



$ solution: $

这一题出得真的很好,将原本一道矩阵快速幂硬生生加入组合数的标签,还那么没有违和感,那么让人看不出来。所以做这道题必须先知道(矩阵快速幂及如何构建递推矩阵)(组合数及二项式定理)。

不知道大家有没有做过洛谷的帕秋莉手环及P哥的桶,这道题中不能有相邻的两个1就是我们在构造这个交错序列时不能连续加入两个1,这个如果直接让我们求方案数(不靠虑一的个数)就是矩阵快速幂的板子了(可以自己推递推方程)。但是这1题偏偏把1的个数搭上了,我们发现1的个数是可以达到 $ 10^8 $ 级别的!所以我们不能直接把1得个数当做一个状态,这里有一个巧妙的避开1的个数的递推方程:

因为我们状态转移时,我们其实只需要知道序列末尾是1还是0,而1的个数我们不妨不管(为什么要折磨自己呢?)我们可以用 $ F[i][j][0/1] $ 为前 $ i $ 位,最后一位为 $ 0/1 $ ,满足条件的序列的1的个数的j次方和(注意是j次方和)。然后我们就可以避开1的个数(因为每一次我们如果要在序列末尾加一个1,就相当于所有长度为i的末尾为一的序列都要加上一个1,然后我们只要求 $ (y+1)^j $ 即可!这个可以用二项式定理搞一下)(这样建出来的矩阵只有90*90可以勉强过)(需要卡常)

后效性:我们避开了一的个数,但是我们需要求零得个数啊!这又怎么办呢?我们把题目要我们求的东西转化一下: $ xayb=(n-y)ayb=\sum_{i=0}{a}C(a,i)ni(-y){a-i}yb $ 这样我们就可以用我们之前设的(满足条件的序列的1的个数的j次方和)的这一维状态求解了!

卡常:因为这一题的模数小于 $ 10^8 $ 不是 $ 10^9 $ 我们矩阵乘法的时候可以多加几次再取模(详情看代码),不然真的很难卡常数!



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set> #define ull unsigned long long
#define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int using namespace std; int n,a,b,m,t,f,tot;
int C[93][93],nf[95]; struct su{
ll s[182][182];
inline void operator *(su x){
su y;
for(rg i=0;i<t;++i)
for(rg j=0;j<t;++j)
y.s[i][j]=0;
for(rg i=0;i<t;++i)
for(rg j=0;j<t;++j){
for(rg k=0;k<t;++k)
y.s[i][j]+=s[i][k]*x.s[k][j];
y.s[i][j]%=m;
}
*this=y;
}
}bas,ans; inline int qr(){
char ch;
while((ch=getchar())<'0'||ch>'9');
int res=ch^48;
while((ch=getchar())>='0'&&ch<='9')
res=res*10+(ch^48);
return res;
} int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
n=qr(); a=qr(); b=qr(); m=qr();
f=a+b+1; t=f<<1; nf[0]=1;
for(rg i=0;i<f;++i){
C[0][i]=1;
bas.s[i][i]=1;
bas.s[f+i][i]=1;
bas.s[0][f+i]=1;
nf[i+1]=(ull)nf[i]*n%m;
}
for(rg i=1;i<f;++i)
for(rg j=i;j<f;++j)
C[i][j]=(C[i][j-1]+C[i-1][j-1])%m,bas.s[i][f+j]=C[i][j];
ans.s[0][0]=1;
while(n){
if(n&1)ans*bas;
bas*bas; n>>=1;
}
for(rg i=0;i<=a;++i){
rg j=a+b-i;
rg x=(ll)C[i][a]*((a-i)&1?-1:1)*nf[i]%m;
rg y=(ans.s[0][j]+ans.s[0][j+f])%m;
tot=(tot+(ll)x*y)%m;
}printf("%d\n",(tot+m)%m);
return 0;
}

[CQOI2018]交错序列 (矩阵快速幂,数论)的更多相关文章

  1. HDU6395 Sequence(矩阵快速幂+数论分块)

    题意: F(1)=A,F(2)=B,F(n)=C*F(n-2)+D*F(n-1)+P/n 给定ABCDPn,求F(n) mod 1e9+7 思路: P/n在一段n里是不变的,可以数论分块,再在每一段里 ...

  2. 51nod 1197 字符串的数量 V2(矩阵快速幂+数论?)

    接上一篇,那个递推式显然可以用矩阵快速幂优化...自己随便YY了下就出来了,学了一下怎么用LaTeX画公式,LaTeX真是个好东西!嘿嘿嘿 如上图.(刚画错了一发...已更新 然后就可以过V2了 or ...

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

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

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

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

  5. 【BZOJ4002】[JLOI2015]有意义的字符串(数论,矩阵快速幂)

    [BZOJ4002][JLOI2015]有意义的字符串(数论,矩阵快速幂) 题面 BZOJ 洛谷 题解 发现我这种题总是做不动... 令\(A=\frac{b+\sqrt d}{2},B=\frac{ ...

  6. 【BZOJ2432】【NOI2011】兔农(数论,矩阵快速幂)

    [BZOJ2432][NOI2011]兔农(数论,矩阵快速幂) 题面 BZOJ 题解 这题\(75\)分就是送的,我什么都不想写. 先手玩一下,发现每次每次出现\(mod\ K=1\)的数之后 把它减 ...

  7. cf 450b 矩阵快速幂(数论取模 一大坑点啊)

    Jzzhu has invented a kind of sequences, they meet the following property: You are given x and y, ple ...

  8. 数学--数论--HDU - 6395 Let us define a sequence as below 分段矩阵快速幂

    Your job is simple, for each task, you should output Fn module 109+7. Input The first line has only ...

  9. HDU 2256 Problem of Precision 数论矩阵快速幂

    题目要求求出(√2+√3)2n的整数部分再mod 1024. (√2+√3)2n=(5+2√6)n 如果直接计算,用double存值,当n很大的时候,精度损失会变大,无法得到想要的结果. 我们发现(5 ...

随机推荐

  1. selenium之下载

    # 测试下载功能,保存文件到指定的目录 # 不同的浏览器配置是不同的,本例使用chrome浏览器 # author:gongxr # date:2017-07-25 import time from ...

  2. bzoj 2202 [HNOI2010] Bounce 弹飞绵羊(分块)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2002 思路:和之前那道树分块的题很像,只不过那道是在树上,这道简单些在序列上 还是维护两个数 ...

  3. [luogu5008]逛庭院

    首先我们看到数据范围.妈耶!数据这么大,一开始还想用个DP来做,但是看着就不行,那么根据这个数据范围,我们大致可以猜到这道题的算法是一个贪心,那么我们怎么贪呢? 我们首先还是先画一个图: 样例解释一下 ...

  4. 安装Prometheus-Opeartor

    一.下载git clone clone https://github.com/coreos/prometheus-operator.git或:wget https://github.com/coreo ...

  5. luogu3320 寻宝游戏 (dfs序+倍增lca+set)

    一定是从随便某个点开始,然后按着dfs序的顺序跑一圈是最好的 所以说,新加一个点x,就减少了dis(pre,next),增加了dis(pre,x),dis(x,nxt) 删掉一个点同理 这个可以用se ...

  6. bzoj3277 串 (后缀数组+二分答案+ST表)

    常见操作:先把所有串都连到一起,但中间加上一个特殊的符号(不能在原串中/出现过)作为分割 由于全部的子串就等于所有后缀的所有前缀,那我们对于每一个后缀,去求一个最长的前缀,来满足这个前缀在至少K个原串 ...

  7. luogu3810 陌上花开 (cdq分治)

    求三维偏序 设三维为a,b,c.先对a排序,这样i的偏序就只能<i. 然而排序的时候需要三个维度都判断一遍,最后还要去重,不然会出现实际应该记答案的数出现在它后面的情况. (排序用的函数里不要写 ...

  8. SwitchButton 开关按钮 的多种实现方式 (附源码DEMO)

    http://blog.csdn.net/vipzjyno1/article/details/23707149 Switch开关android源码SwitchButton 刚开始接触开关样式的按钮是在 ...

  9. luogu P4198 楼房重建——线段树

    题目大意: 小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,其中Hi为第i栋楼房的高度.如果这栋楼房上任何一个高度大于0的点与(0,0)的连线没有与之前的线 ...

  10. 【洛谷P5020】货币系统 完全背包

    题目大意:给定 N 个数,求在这 N 个数中至少选出几个数能表示出所有数字,输出最少的个数. 题解:由于只有小的数字可以表示大的数字,因此首先需要对这 N 个数字进行从小到大排序.排序之后就变成一道不 ...