码迷,mamicode.com
首页 > 其他好文 > 详细

ACM-矩阵专题

时间:2015-04-20 11:16:38      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:矩阵   数学   

之前写过一篇矩阵的总结,但那时题目做得很少.点击打开链接

这次刷了个专题,写个总结 点击打开链接

水题:

A.典型的斐波那契递推构造

B.矩阵构造,就是按列递推

C.水题

G.水题

结合/技巧问题:

就是有的时候要计算C=A*B  C^N.这时候可能A * B的范围很大,那么就算A*(B*A)^(N-1)*B即可

E结合

H   S(N)=A+A^2+A^3+A^4+.....+A^N 两种方法,一种是二分即当N为偶数S(N)=(A+A^2+...+A^(N/2)(E+A^(N/2)),奇数S(N)=(A+A^2+...+A^(N/2)(E+A^(N/2))+A^N,

另一种是构造矩阵[S(N),An]



找规律:

1. 已知a+b,ab 求a^n+b^n. 设f(n)=a^n+b^n.

则f(n+1)=f(n)*(a+b)=a^(n+1)+b^(n+1)+ab(a^(n-1)+b^(n-1))

=(a+b)f(n)-abf(n-1)

2. L这个题的规律,打表找吧.

3.M 求 ceil((a+√b)^n)%m 的结果. 利用题目给定的b的范围发现可以写成ceil((a+√b)^n + (a-√b)^n)%m.等价于a^n+b^n 和1一样了

4.R   F[0] = a   F[1] = b   F[n] = F[n-1] * F[n-2] ( n > 1 )  求Fn, 这个拆分下发现

f(n)是斐波那契数列的第n项    F(n) = a^f(n-1)*b^f(n)

然后由费马小定理
    a^f(n-1) = a^(f(n-1)%1000000006) (mod 1000000007)
    b^f(n) = b^(f(n)%1000000006) (mod 1000000007) 这2个直接快速幂就行了

f(n)%1000000006这个用矩阵快速幂可以求


5.(f[1]+f[2]+...+f[n])=f[n+2]-1 

构造一个矩阵, 使得各行和各列的值不同.
矩阵的上三角全为"1"
矩阵的下三角全为"-1"
对角线"1","0"交替.
如n = 4,对应矩阵为:
1 1 1 1
1 1 0 -1
1 1 -1 -1
0 -1 -1 -1


矩阵模版:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int MOD = 1000000007;
#define MaxSize 5
typedef long long type;
typedef long long LL;
LL n,k;
struct Mat{
    type arr[MaxSize][MaxSize];
    int r,l;
    Mat(int r=0,int l=0){
        this->r=r;
        this->l=l;
        memset(arr,0,sizeof(arr));
    }
    Mat operator * (const Mat &x){
        Mat ret(r,x.l);
        for(int i = 0;i<r;i++)
            for(int j = 0;j<l;j++)
                for(int k = 0;k<x.l;k++)
                    ret.arr[i][j] = (ret.arr[i][j]+arr[i][k]*x.arr[k][j] %MOD)%MOD;
        return ret;
    }

};
Mat pow_mat(LL n,Mat basic){
    Mat ret(2,2);
    ret.arr[0][0]=ret.arr[1][1]=1;
    while(n>0){
        if(n&1)
            ret = ret*basic;
        basic = basic*basic;
        n>>=1;
    }return ret;
}
LL solve(LL nn){
    LL ret;
    if(nn==1)
        return 1;
    Mat e(2,2);
    e.arr[0][0]=e.arr[0][1]=e.arr[1][0]=1;
    e = pow_mat(nn/2,e);
    ret = e.arr[0][0] * (LL)pow(nn/2,k) +1;
    ret = ret * solve(nn/2)%MOD;
    if(nn&1)
        ret = ret*(pow_mat(nn,e).arr[0][0])%MOD;
    return ret;
}
int main(){
    int cas=1;
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%I64d%d",&n,&MOD);
        printf("Case %d: ",cas++);
        Mat e(2,2);
        e.arr[0][0]=e.arr[0][1]=e.arr[1][0]=1;
        e = pow_mat(n,e);
        int ans = (e.arr[0][0] + e.arr[1][0]-1+MOD)%MOD;
        if(ans==0){
            puts("No");
            continue;
        }puts("Yes");
        for(int i = 0;i<ans;i++){
            for(int j = 0;j<i;j++)
                printf("-1 ");
            if(i%2==0) {
                if(i==ans-1) printf("0\n");
                else printf("0 ");
            }
            if(i%2==1) {
                if(i==ans-1) printf("1\n");
                else printf("1 ");
            }
            for(int j = i+1;j<ans;j++)
                if(j==ans-1)  printf("1\n");
                else printf("1 ");
        }


    }
    return 0;
}


ACM-矩阵专题

标签:矩阵   数学   

原文地址:http://blog.csdn.net/gg_gogoing/article/details/45146651

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!