现在的位置: 首页 > 综合 > 正文

2013 ACM/ICPC 长沙赛区湖大全国邀请赛 A题(6.1修订)

2017年07月15日 ⁄ 综合 ⁄ 共 2318字 ⁄ 字号 评论关闭

小记:这次大赛教训惨重,ACM的路任重道远,现在努力做出每道题的解题报告吧。以此来抚慰我那惨痛的心灵。

题目:

这个题目名叫So easy!  当初看了 就想A, 现在看来这估计就是个陷阱,数学不好的必被坑。

由于我是用word写好的,但是里面的数学符号复制不出来,所以我就用图片来描述好了。

Solution

递推求通项公式的特征根的方法可以看这个:

http://sx.fjjcjy.com/upLoad/news/month_1203/201203091236588965.doc(这是的文件,点击就直接下载了)

(之前没A之前,犯了右乘和左乘的理解错误,改过来就差不多了,之前的代码提交的错了,除了左乘和右乘理解错误外,还有就是没有将进行快速幂的矩阵里的负元素变成正数(通过加M,即要取模的值变成正数,如果有负数的话,进行快速幂是错的),全改了之后就A了。)(6.1 修改)

在快速幂的时候就进行取模运算,防溢出。

进过转换之后,我们发现这题纯粹就是一道简单的矩阵快速幂的模板题。顿时觉得数学是门非常深奥的课程,需要不断的去学习探索。败在这题之下,确实只能怪自己基础不扎

实,受教了。模板我的博客里有。

这题,经过几天的思考,在wuzhengkai大神的点拨下,以及另一位神犇(链接没找到)的帮助下,顿悟了。在此特地感谢!

//下面贴上我的代码,湖大OJ 暂时打不开,所以还不知道正确与否,不过根据我自己生成的随机数据,理论上应该没错。

下面是错误的代码:

#include <iostream>
#include <stdio.h>

using namespace std;

#define N 2
#define ll unsigned long long

struct Matrix {
    ll v[N][N];
};

Matrix A,B={1,0,0,1};
ll M;

Matrix mul(Matrix m1,Matrix m2,ll M){
    int i,j,k;
    Matrix c;
    for(i=0;i<N;i++)for(j=0;j<N;j++){
        c.v[i][j]=0;
        for(k=0;k<N;k++)
            c.v[i][j]+=(m1.v[i][k]*m2.v[k][j])%M;
        c.v[i][j] %= M;
    }
    return c;
}

Matrix Mpow(Matrix A,Matrix B,ll n,ll M){
    Matrix x=A,c=B;
    while(n>=1){
        if(n&1)c=mul(c,x,M);
        n>>=1;
        x=mul(x,x,M);
    }
    return c;
}

int main() {
    //freopen("d:\\in.txt","r",stdin);
    //freopen("d:\\out.txt","w",stdout);
    //int flag = 0;
    ll n, a, b;
    while(cin>>a>>b>>n>>M){
        /*if(flag)cout << endl;
        else flag = 1;*/

        if(n == 1){
            cout << (2*a) % M <<endl;continue;
        }
        if(n == 2){
            cout << (2*a*a + 2*b) % M <<endl;continue;
        }
        A.v[0][0] = 2*a;
        A.v[0][1] = b - a*a ;
        A.v[1][0] = 1;
        A.v[1][1] = 0;
        Matrix p = Mpow(A,B,n-2,M), q = {2*a*a + 2*b, 0, 2*a, 0};
        p = mul(p,q,M);
        cout<<p.v[0][0]<<endl;
    }
    return 0;
}

改正后的A过的代码:(6.1修改)

#include <iostream>
#include <stdio.h>

using namespace std;

#define N 2
#define ll long long

struct Matrix {
    ll v[N][N];
};

Matrix A,B={1L,0L,0L,1L};
ll M;

Matrix mul(Matrix m1,Matrix m2,ll M){
    int i,j,k;
    Matrix c;
    for(i = 0; i < N; i++)
        for(j = 0; j < N; j++){
            c.v[i][j] = 0;
            for(k = 0; k < N; k++){
                c.v[i][j] += (m1.v[i][k]*m2.v[k][j])%M;
                c.v[i][j] %= M;
            }
            c.v[i][j] %= M;
    }
    return c;
}

Matrix Mpow(Matrix A,Matrix B,ll n,ll M){
    Matrix x = A,c = B;
    while(n >= 1){
        if(n&1L)c = mul(c,x,M);
        n >>= 1;
        x = mul(x,x,M);
    }
    return c;
}

int main() {
    //freopen("F:\\problem A\\in.txt","r",stdin);
    //freopen("F:\\problem A\\out.txt","w",stdout);
    ll n, a, b, t;
    while(cin>>a>>b>>n>>M){
        if(n == 1){
            cout << (2*(a%M)) % M <<endl;continue;
        }
        if(n == 2){
            cout << ((2*((a%M)*(a%M))%M)%M + (2*b)%M) % M <<endl;continue;
        }
        A.v[0][0] = (2*(a%M)) % M;
        t = a;
        t *= a;
        A.v[0][1] = 1;
        t = b - t;
        while(t < 0)t += M;
        A.v[1][0] = t;
        A.v[1][1] = 0;
        Matrix p = Mpow(A,B,n-2,M), q = {((2*((a%M)*(a%M))%M)%M + (2*b)%M) % M, (2*(a%M)) % M, 0L, 0L};
        p = mul(q,p,M);
        cout<<p.v[0][0]<<endl;
    }
    return 0;
}

抱歉!评论已关闭.