P1397 [NOI2013]矩阵游戏

一波化式子,$f[1][m]=a^{m-1}+b\sum_{i=0}^{m-2}a^i$,用快速幂+逆元求等比数列可以做到$logm$

设$v=a^{m-1},k=\sum_{i=0}^{m-2}a^i$

那么$f[1][m]=v+bk$

再对纵列化一波式子,$f[i][m]=f[i-1][m]*vc+bk+vd$

如果你直接上个矩乘可以拿到65的好分数

#include<iostream>
#include<cstdio>
#include<cstring>
#define ri register int
using namespace std;
typedef long long ll;
const ll P=1e9+;
const ll W=1e9;
char q[];
struct bnum{
ll a[],len;
bnum(){memset(a,,sizeof(a));len=;}
void init(){
scanf("%s",q); int z=; len=;
for(ri i=strlen(q)-;i>=;--i){
a[len]+=(q[i]-)*z; z*=;
if(z==W) z=,++len;
}
while(!a[len]&&len) --len;
}
ll mod(){
ll re=;
for(ri i=;i<=len;++i) re=(re*W+a[i])%P;
return re;
}
void rem1(){
--a[];
for(ri i=;a[i]<;++i) a[i]+=W,--a[i+];
while(!a[len]&&len) --len;
}
bnum div2(){
bnum c; c.len=len; ll x=;
for(ri i=len;i;--i)
x=x*W+a[i],c.a[i]=x/,x%=;
while(!c.a[c.len]&&c.len) --c.len;
return c;
}
}n,m;
struct mat{
ll a[][];
mat(){memset(a,,sizeof(a));}
mat operator * (const mat &b) const{
mat c;
for(ri i=;i<;++i)
for(ri j=;j<;++j)
for(ri k=;k<;++k)
c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j]%P)%P;
return c;
}
}s,p;
ll Pow(ll x,ll y){
ll re=;
for(;y;y>>=,x=x*x%P) if(y&) re=re*x%P;
return re;
}
ll Pow_b(ll x,bnum y){
ll re=;
for(;y.len;y=y.div2(),x=x*x%P) if(y.a[]&) re=re*x%P;
return re;
}
mat Pow_m(mat x,bnum y){
mat re; for(ri i=;i<;++i) re.a[i][i]=;
for(;y.len;y=y.div2(),x=x*x) if(y.a[]&) re=re*x;
return re;
}
int main(){
ll a,b,c,d,v,k;
n.init(); m.init(); n.rem1(); m.rem1();
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
v=Pow_b(a,m);
if(a>) k=(v-+P)%P*Pow((a-+P)%P,P-)%P;
else k=m.mod();
s.a[][]=(b*k+v)%P; s.a[][]=(b*k%P+v*d%P)%P;
p.a[][]=v*c%P; p.a[][]=p.a[][]=;
p=Pow_m(p,n); s=s*p;
printf("%lld",s.a[][]);
return ;
}

65pts

观察发现,这个矩乘可以再化:

$f[n][m]=(v+bk)(vc)^{n-1}+(bk+vd)\sum_{i=0}^{n-2}(vc)^i$

观察这个式子,复杂度主要在快速幂上,复杂度$O(logn+logm)$

考虑缩小$n,m$

假设存在:$a^n=a^{n-x}\, mod \;  p$,$p$为质数

$\therefore  a^x=1\, mod \;  p$

根据费马小定理,$x=p-1$

$\therefore  a^n=a^{n\, mod\, p-1}\, mod \;  p$

输入$n,m$时记下它们$mod\, p,p-1$的值,代入式子即可

注意等比数列公比$=1$时需要特判

#include<iostream>
#include<cstdio>
#include<cstring>
#define ri register int
using namespace std;
typedef long long ll;
const ll P=1e9+;
ll a,b,c,d,v,k,n,m,_n,_m,a_,k_,v_;
void init(){
char c=getchar();
while(c<''||c>'') c=getchar();
while(''<=c&&c<=''){
n=(n*+c-)%P;
_n=(_n*+c-)%(P-);
c=getchar();
}c=getchar();
while(c<''||c>'') c=getchar();
while(''<=c&&c<=''){
m=(m*+c-)%P;
_m=(_m*+c-)%(P-);
c=getchar();
}
}
ll Pow(ll x,ll y){
ll re=;
for(;y;y>>=,x=x*x%P) if(y&) re=re*x%P;
return re;
}
int main(){
init(); scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
n=(n-+P)%P; _n=(_n-+P-)%(P-);
m=(m-+P)%P; _m=(_m-+P-)%(P-);
v=Pow(a,_m);
k=a>?(v-+P)*Pow(a-+P,P-)%P:m;
a_=v*c%P; v_=Pow(a_,_n);
k_=a_>?(v_-+P)*Pow(a_-+P,P-)%P:n;
printf("%lld",((v+b*k)%P*v_%P+(b*k+v*d)%P*k_%P)%P);
return ;
}

P1397 [NOI2013]矩阵游戏(递推)的更多相关文章

  1. luogu P1397 [NOI2013]矩阵游戏

    传送门 题目中那两个递推式显然可以写成矩乘的形式,然后十进制快速幂即可.这里不再赘述 只有两个递推式,我们可以考虑一波推式子,首先第一行的元素应该分别是\(1,a+b,a^2+ab+b,a^3+a^2 ...

  2. 洛谷P1397 [NOI2013]矩阵游戏

    矩阵快速幂+费马小定理 矩阵也是可以跑费马小定理的,但是要注意这个: (图是盗来的QAQ) 就是说如果矩阵a[i][i]都是相等的,那么就是mod p 而不是mod p-1了 #include< ...

  3. 洛谷P1397 [NOI2013]矩阵游戏(十进制矩阵快速幂)

    题意 题目链接 Sol 感觉做这题只要对矩阵乘法理解的稍微一点就能做出来对于每一行构造一个矩阵A = a 1      0 b列与列之间的矩阵为B = c 1      0 d最终答案为$A^{n - ...

  4. P1397 [NOI2013]矩阵游戏

    传送门 首先显然可以矩乘快速幂然后 $T$ 飞 看一眼题解发现因为这一题矩阵的特殊性所以可以对矩阵的次数欧拉降幂 然而我并不懂证明,所以我选择暴力乱搞的做法 十进制快速幂,然后注意一下常数,还有矩阵乘 ...

  5. bzoj 3240: [Noi2013]矩阵游戏 矩阵乘法+十进制快速幂+常数优化

    3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 613  Solved: 256[Submit][Status] ...

  6. BZOJ 3240: [Noi2013]矩阵游戏

    3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1586  Solved: 698[Submit][Status ...

  7. BZOJ 3240([Noi2013]矩阵游戏-费马小定理【矩阵推论】-%*s-快速读入)

    3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec   Memory Limit: 256 MB Submit: 123   Solved: 73 [ Submit][ St ...

  8. (十进制高速幂+矩阵优化)BZOJ 3240 3240: [Noi2013]矩阵游戏

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=3240 3240: [Noi2013]矩阵游戏 Time Limit: 10 Sec  M ...

  9. HDU 4914 Linear recursive sequence(矩阵乘法递推的优化)

    题解见X姐的论文 矩阵乘法递推的优化.仅仅是mark一下. .

随机推荐

  1. CF718C Sasha and Array 线段树 + 矩阵乘法

    有两个操作: 将 $[l,r]$所有数 + $x$ 求 $\sum_{i=l}^{r}fib(i)$ $n=m=10^5$   直接求不好求,改成矩阵乘法的形式:  $a_{i}=M^x\times ...

  2. RedHat下yum配置为本地或者CentOs

    由于RedHat公司将yum源作为服务给用户提供,所以不能free给大家确实挺失望的,不过还好能够在RedHat上配置本地的Yum源,或者CentOS的Yum源. 这里提供两种方式,一种是配置本地的, ...

  3. JMS学习二(简单的ActiveMQ实例)

    下载安装ActiveMQ服务,下载地址当然可以去官网下载 http://activemq.apache.org/download-archives.html ActiveMQ安装很简单,下载解压后到b ...

  4. iOS 消息转发以及 NSProxy 实战

    最后更新: 2018-01-17 一.消息派发机制-NSObject 在 iOS 开发中, 调用对象的方法就是给对象发送一个消息.了解消息的派发机制对于iOS开发来说是一个很实用且强大的工具, 下面我 ...

  5. [UPC10525]:Dove打扑克(暴力+模拟)

    题目描述 $Dove$和$Cicada$是好朋友,他们经常在一起打扑克来消遣时光,但是他们打的扑克有不同的玩法. 最开始时,牌桌上会有$n$个牌堆,每个牌堆有且仅有一张牌,第$i$个牌堆里里里那个扑克 ...

  6. [CSP-S模拟测试]:取石子(博弈论+DP)

    题目描述 有三堆石子,它们的石子个数分别为$x,y,z$.$A$和$B$正在博弈,由$A$先手,双方轮流操作.每次操作是指,选择若干堆($1-3$堆)石子,从中各取出相同数量的石子(不能$1$个都不取 ...

  7. 修改win10 capslock键成esc键 vim

    桌面编辑一个文件CapsLock2Esc.reg Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentCont ...

  8. Python基本语法_基本数据类型_序列类型详解

    目录 目录 序列 序列的标准操作符 切片操作符 一个例子 字符串的连接 序列的功能函数 enumerate 枚举出序列对象的元素 len 获取序列对象的长度 min 取出sequence中的最小值 m ...

  9. VirtualBox主机虚拟机互通

    首先使用的是桥接模式,桥接模式相当于是使用Hub来把主机以及虚拟机进行关联: 然后就是选择“界面名称”,这里吐槽一下,这里其实是“Interface Name”,Interface代表的是网卡的接口, ...

  10. Gradle原理动画讲解(五)

    Gradle原理动画讲解