题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6395

因为题目数据范围太大,又存在递推关系,用矩阵快速幂来加快递推。

每一项递推时  加的下取整的数随着n变化,但因为下取整有连续性(n一段区间下取整的数是相同的),可以分块,相同的用矩阵快速幂加速

想了好久。。如果最小的开始的值是【p/i】的数为i,那连续的一段长度是【p/(p/i)】-i+1,但为什么分段数是根号n级别啊?。。。

套矩阵快速幂,时间复杂度O(sqrt(n) * log(n))

⎧⎩⎨⎪⎪⎪⎪⎪⎪F1F2Fn===ABC⋅Fn−2+D⋅Fn−1+⌊Pn⌋
⎧⎩⎨⎪⎪⎪⎪⎪⎪F1F2Fn===ABC⋅Fn−2+D⋅Fn−1+⌊Pn⌋

一个递推关系式可以用矩阵乘法来表示递推关系

有两种写法

至于怎么求特征值矩阵(用来加速的那个矩阵),就是根据关系式,观察前后两个的变化与联系填就好了

为了写着省事用了第一种,但其实它复杂度高,推荐第二种

坑:

1.n=1 和 n=2 要特判

2.如果n>p,最后加的下取整的数为0,要特判,且特判的时候,注意长度不是【n-p】,p可能比2小,而我们矩阵的第一项是从F2 开始的,应为[n-max(2,p)]

3.矩阵快速幂三层循环的变量不要写错,。。一开始把第三层的k写成 i 死循环了

4.运算符重载后不要用scanf输入,在一些oj上会超时

5.max、min函数比较的是同一种变量

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
const int p=1e9+;
ll aa,b,c,d,mo,n;
struct matrix
{
ll a[][];
ll* operator [](int x) {return a[x];}//这里是*不是&
matrix operator *(matrix b)//重载*运算符
{
matrix c;
memset(c.a,,sizeof(c.a));
ll tmp;
for (int i=;i<=;i++) {
tmp=;
for (int j=;j<=;c[i][j]=tmp%p,tmp=,j++)
for (int k=;k<=;k++) tmp+=(a[i][k]*b[k][j])%p;
}
//前提p^3不爆LL可以在第二层再取模
return c;
}
matrix operator ^(ll T)
{
matrix a=*this,b;//this是指针,所以是*this,这样才可以保证原来的a并不改变
memset(b.a,,sizeof(b.a));
for (int i=;i<=;i++) b[i][i]=;
for (;T;a=a*a,T>>=) if (T&) b=b*a;
return b;
}
};
matrix ans;
void work(ll ci,ll chang){
ans[][]=chang;
matrix node;
node[][]=d,node[][]=,node[][]=;
node[][]=c,node[][]=,node[][]=;
node[][]=,node[][]=,node[][]=;
matrix ping=node^ci;
ans=ans*ping;
}
int main(){
int t;
scanf("%d",&t);
for(int p=;p<=t;p++){
cin>>aa>>b>>c>>d>>mo>>n;
if(n==){
cout<<aa;continue;//运算符重载后不要用scanf输入
}
else if(n==){
cout<<b;continue;
}
else{ ans[][]=b,ans[][]=aa;
for(int i=;i<=;i++){
ans[][i]=;ans[][i]=;
}
for(ll i=,j;i<=n;i=j+){
if(mo/i==)break;
j=mo/(mo/i);
if(n<j)j=n;
work(j-i+,mo/i);
}
ll w=;
if(mo>w)w=mo;
if(n>mo)work(n-w,);//一定不要直接用n-mo,如果mo是1会错误,要与2进行大小比较
cout<<ans[][]<<endl;
}
}
return ;
}

再附上一个矩阵快速幂的板子:

struct matrix
{
int n,m;
LL a[maxk][maxk];
LL* operator [](int x) {return a[x];}//这里是*不是&
matrix operator *(matrix b)
{
int i,j,kk;
matrix c;
c.n=n,c.m=b.m;
memset(c.a,,sizeof(c.a));
LL tmp;
for (i=;i<=n;i++) for (j=,tmp=;j<=b.m;c[i][j]=tmp%p,tmp=,j++)
for (kk=;kk<=m;kk++) tmp+=a[i][kk]*b[kk][j];
return c;
}
matrix operator ^(LL T)
{
matrix a=*this,b;//this是指针,所以是*this,这样才可以保证原来的a并不改变
memset(b.a,,sizeof(b.a));
b.n=n,b.m=m;
for (int i=;i<=n;i++) b[i][i]=;
for (;T;a=a*a,T>>=) if (T&) b=b*a;
return b;
}
};
/*
ll* 返回的是指针,也就是 a[x]是一个指针(相当于返回第x行第0列的数值的指针),a[x][y]是一个数值,在外面调用a[x][y]时,相当于(m.a[x])[y]

F1F2Fn===ABC⋅Fn−2+D⋅Fn−1+⌊Pn⌋

[hdu-6395]Sequence 分块+矩阵快速幂的更多相关文章

  1. HDU 6395 Sequence 【矩阵快速幂 && 暴力】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6395 Sequence Time Limit: 4000/2000 MS (Java/Others)   ...

  2. HDU 5667 Sequence(矩阵快速幂)

    Problem Description Holion August will eat every thing he has found. Now there are many foods,but he ...

  3. HDU 5667 Sequence【矩阵快速幂+费马小定理】

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5667 题意: Lcomyn 是个很厉害的选手,除了喜欢写17kb+的代码题,偶尔还会写数学题.他找到 ...

  4. Sequence( 分块+矩阵快速幂 )

    题目链接 #include<bits/stdc++.h> using namespace std; #define e exp(1) #define pi acos(-1) #define ...

  5. 杭电多校第七场 1010 Sequence(除法分块+矩阵快速幂)

    Sequence Problem Description Let us define a sequence as below f1=A f2=B fn=C*fn-2+D*fn-1+[p/n] Your ...

  6. HDU.1575 Tr A ( 矩阵快速幂)

    HDU.1575 Tr A ( 矩阵快速幂) 点我挑战题目 题意分析 直接求矩阵A^K的结果,然后计算正对角线,即左上到右下对角线的和,结果模9973后输出即可. 由于此题矩阵直接给出的,题目比较裸. ...

  7. hdu 3117 Fibonacci Numbers 矩阵快速幂+公式

    斐波那契数列后四位可以用快速幂取模(模10000)算出.前四位要用公式推 HDU 3117 Fibonacci Numbers(矩阵快速幂+公式) f(n)=(((1+√5)/2)^n+((1-√5) ...

  8. HDU - 6395 Sequence (整除分块+矩阵快速幂)

    定义数列: $\left\{\begin{eqnarray*} F_1 &=& A \\ F_2 &=& B \\ F_n &=& C\cdot{}F_ ...

  9. HDU-6395 多校7 Sequence(除法分块+矩阵快速幂)

    Sequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total ...

随机推荐

  1. VC6下深入理解new[]和delete[](在多线程下new和delete的时候,必须选择上多线程库,不然可能造成进程崩溃)

    多少年了,一直处于C与C++混用的状态,申请空间一直用malloc,释放空间一直用free,为什么?因为他们好理解易操作,就如同输出一直用printf而不用<<,输入一直用scanf而不用 ...

  2. 一些自成系统、完备的教程(链接、博客、github等)

    0. Linus shell Advanced Bash-Scripting Guide 1. latex Some applicable LATEX's info 14 课的个人 CV 制作: 15 ...

  3. git 命令修改commit时的用户名和邮箱地址

    1.介绍 在git的用户名和邮箱是有一个仓库和全局之分的,在利用vs插件是也有显示:

  4. Linux(CentOS 7)+ Nginx(1.10.2)+ Mysql(5.7.16)+ PHP(7.0.12)完整环境搭建

    首先安装Linux系统,我以虚拟机安装来做示例,先去下载 VitualBox,这是一款开源的虚拟机软件,https://www.virtualbox.org 官网地址.或者是VMware,www.vm ...

  5. typescript Json Convert

    关键代码 this.data={}; // json string this.dataStr=JSON.stringify(this.data); // json object this.conver ...

  6. ASP.NET Core 配置身份验证

    以AspUser的Password为例,去掉最少1个大写字母,1个小写字母等等坑爹的要求在Startup的ConfigureServices中进行配置 services.Configure<Id ...

  7. XF 主从页面

    using System; using Xamarin.Forms; using Xamarin.Forms.Xaml; [assembly: XamlCompilation (XamlCompila ...

  8. String的本质是一个char*,只是以类的形式提供,使用起来比较方便

    String的本质是一个char*,只是以类的形式提供,使用起来比较方便 Class String {private: char* m_data;}摘自<后台开发 核心技术与应用实践__徐晓鑫& ...

  9. Hamcrest、Mockito 专题

    UT中需要的jar Junit4.1X.jar hamcrest-library-1.x.jar hamcrest-core-l.x.jar mockito-all-1.10.x.jar Junit ...

  10. TLD单目标跟踪算法程序详解--OpenTLD Code 详解

    TLD算法原理介绍:http://www.cnblogs.com/liuyihai/p/8306419.html OpenTLD源代码页: https://github.com/zk00006/Ope ...