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

来源:互联网 发布:英雄联盟免费皮肤软件 编辑:程序博客网 时间:2024/04/29 19:10

小记:这次大赛教训惨重,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 longstruct 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 longstruct 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;}



原创粉丝点击