矩阵练习3
2014-03-25 16:49
162 查看
POJ 3292 大湿给的TAG是佩尔方程,但是我直接用筛法变形给过了。。。
http://poj.org/problem?id=3292这道题我暑假集训的时候就过了。。。要去看代码和题意的去翻我前面的CSDN。。。
POJ 1320 http://poj.org/problem?id=1320 题意比较操蛋,我找DL翻译的- - 然后翻译了之后大致意思是给你这个人住的号码为a,街道尽头为b
然后要使得1+2+3+..a-1=a+1+a+2+...b相等,求出前十组满足条件的a和b的解。。首先很容易想到左边右边都是等差数列的和的形式,求和可以得到
2a^2=b^2+b然而根据大湿的TAG,我们知道佩尔方程是为了求解形如x^2-ty^2=1的二元二次不定方程的正整数解的一个方程,而且t不能是完全平方数。。然后
接下来的工作就是想办法凑出一个佩尔方程的形式了。。其实也蛮好凑得。。左右两边乘个4有 8a^2=4b^2+4b====>(2b+1)^2-8a^2=1 然后换元---->2b+1=x ,a=y,t=8
就转化为x^2-8y^2=1的形式。且显然第一组解为x=3 y=1,而经过递推可以得到xi+1=x1xi+ty1yi yi+1=x1yi+y1xi,是故又可以构造一个2*2的矩阵来求解了。。
在这里矩阵也好构造的很。。。
| x1 ty1 | | xi | | xi+1 |
| y1 x1 | *| yi |=| yi+1 | 然后剩下的就又有回到基本的求解过程了。。
HDU 4291
http://acm.hdu.edu.cn/showproblem.php?pid=4291
要求 g(g(g(n))) mod 109 + 7 已知g(n) = 3g(n - 1) + g(n - 2)g(1) = 1 g(0) = 0。
g(n)的矩阵构造已经是小菜一碟了,但是这里难处理的是三层迭代的过程,一开始很傻很天真以为可以把G(n)一层一层的给化掉,然后BALL用没有,然后这题就实在没办法动手,大湿给的TAG是暴力枚举循环节,大致猜到了那就还得求两个循环节是多少才行,但是又不会。。大湿只好告诉了我怎么暴力找循环节 从a=g(1),b=g(0)开始 求出后一个数,后一个数c对当前循环节取模得到一个新的数取代掉a,而a顺势取代掉b 直到重新有a=g(1),b=g(0)的时候证明该层循环节已经找到。。继续把这个数当做下一层用来取模的数找到内层的循环节,然后找到了题目就直接是求先对每一阶的G(n)快速幂中取了模,然后求出结果来了。。。
再附上暴力枚举循环节的代码
HDU 3483
http://acm.hdu.edu.cn/showproblem.php?pid=3483
构造矩阵十分巧妙。
![](http://acm.hdu.edu.cn/data/images/C295-1006-1.jpg)
就是求那货。。。
已知N x M
又是求和的式子,前面已经做到过好几次了,所以这一次不出意外肯定是把sn放到最后然后通过一个矩阵变成sn+1的形式了
然后再写一写有:sn+1=sn+(n+1)^x*x^n+1
首先再次感谢大湿原来给我出过一道
n
Σi^50 的题目,这道题目教会我再求i^k--->(i+1)^k的过程中,我们可以讲(i+1)^k二项展开来构造矩阵
i=0
所以这道题一开始的思路也是这样,把(n+1)^x顺势二项展开得到了一个式子,但是在x^n+1那里又被卡住了2天,最后大湿提醒我说x是已知的,可以提个x出来放进二项展开的
式子中去,终于恍然大悟,遂构造了(x+2)*(x+2)阶的矩阵进行求解,然后过了。。
![](http://img.blog.csdn.net/20140325164549828?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTQ4MTc1Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
矩阵专题到此暂时告一段落了。。。刷了这些题,不知道有没有什么很大的用处,可能也就是把自己的大脑适当的开发了一下吧。。但是开发了一下总比让大脑生锈强,即使再笨,笨鸟也能先飞,只要努力,也许就可以跟那些动脑多的,厉害的人的差距变小一点点了吧。。。。
http://poj.org/problem?id=3292这道题我暑假集训的时候就过了。。。要去看代码和题意的去翻我前面的CSDN。。。
POJ 1320 http://poj.org/problem?id=1320 题意比较操蛋,我找DL翻译的- - 然后翻译了之后大致意思是给你这个人住的号码为a,街道尽头为b
然后要使得1+2+3+..a-1=a+1+a+2+...b相等,求出前十组满足条件的a和b的解。。首先很容易想到左边右边都是等差数列的和的形式,求和可以得到
2a^2=b^2+b然而根据大湿的TAG,我们知道佩尔方程是为了求解形如x^2-ty^2=1的二元二次不定方程的正整数解的一个方程,而且t不能是完全平方数。。然后
接下来的工作就是想办法凑出一个佩尔方程的形式了。。其实也蛮好凑得。。左右两边乘个4有 8a^2=4b^2+4b====>(2b+1)^2-8a^2=1 然后换元---->2b+1=x ,a=y,t=8
就转化为x^2-8y^2=1的形式。且显然第一组解为x=3 y=1,而经过递推可以得到xi+1=x1xi+ty1yi yi+1=x1yi+y1xi,是故又可以构造一个2*2的矩阵来求解了。。
在这里矩阵也好构造的很。。。
| x1 ty1 | | xi | | xi+1 |
| y1 x1 | *| yi |=| yi+1 | 然后剩下的就又有回到基本的求解过程了。。
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; struct juzhen{ long long m[2][2]; }; juzhen mut(juzhen a,juzhen b) { juzhen c; for(long long i=0;i<2;i++) { for(long long j=0;j<2;j++) { c.m[i][j]=0; for(long long k=0;k<2;k++) { c.m[i][j]+=a.m[i][k]*b.m[k][j]; } } } return c; } juzhen pow(juzhen a,long long p) { juzhen ans; ans.m[0][0]=ans.m[1][1]=1; ans.m[0][1]=ans.m[1][0]=0; while(p) { if(p%2==0) { a=mut(a,a); p/=2; } else { ans=mut(ans,a); p--; } } return ans; } int main() { juzhen ans; for(long long i=1;i<=10;i++) { ans.m[0][0]=ans.m[1][1]=3; ans.m[0][1]=8; ans.m[1][0]=1; ans=pow(ans,i); int a=ans.m[1][0]*3+ans.m[1][1]*1; int b=(ans.m[0][0]*3+ans.m[0][1]*1-1)/2; printf("%10d%10d\n",a,b); } return 0; }
HDU 4291
http://acm.hdu.edu.cn/showproblem.php?pid=4291
要求 g(g(g(n))) mod 109 + 7 已知g(n) = 3g(n - 1) + g(n - 2)g(1) = 1 g(0) = 0。
g(n)的矩阵构造已经是小菜一碟了,但是这里难处理的是三层迭代的过程,一开始很傻很天真以为可以把G(n)一层一层的给化掉,然后BALL用没有,然后这题就实在没办法动手,大湿给的TAG是暴力枚举循环节,大致猜到了那就还得求两个循环节是多少才行,但是又不会。。大湿只好告诉了我怎么暴力找循环节 从a=g(1),b=g(0)开始 求出后一个数,后一个数c对当前循环节取模得到一个新的数取代掉a,而a顺势取代掉b 直到重新有a=g(1),b=g(0)的时候证明该层循环节已经找到。。继续把这个数当做下一层用来取模的数找到内层的循环节,然后找到了题目就直接是求先对每一阶的G(n)快速幂中取了模,然后求出结果来了。。。
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; const long long mod1=1000000007; const long long mod2=222222224; const long long mod3=183120; long long n; struct juzhen{ long long m[2][2]; }; juzhen mut(juzhen a,juzhen b,long long mod) { juzhen c; /*memset(c.m,0,sizeof(c.m)); for(int i=0;i<2;i++) { c.m[i][i]=1; }*/ for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { c.m[i][j]=0; for(int k=0;k<2;k++) { c.m[i][j]+=(a.m[i][k]*b.m[k][j])%mod; c.m[i][j]%=mod; } } } return c; } long long pow(juzhen a,long long p,long long mod) { juzhen ans; ans.m[0][0]=ans.m[1][1]=1; ans.m[0][1]=ans.m[1][0]=0; while(p) { if(p%2==0) { a=mut(a,a,mod); p/=2; } else { ans=mut(a,ans,mod); p--; } } return ans.m[0][1]; } int main() { while(scanf("%I64d",&n)!=EOF) { if(n==0) { printf("0\n"); } else if(n==1) { printf("1\n"); } else { juzhen ans1; ans1.m[0][0]=3; ans1.m[0][1]=ans1.m[1][0]=1; ans1.m[1][1]=0; long long tmp1=pow(ans1,n,mod1); long long tmp2=pow(ans1,tmp1,mod2); long long tmp3=pow(ans1,tmp2,mod3); printf("%I64d\n",tmp3%mod3); } } return 0; }
再附上暴力枚举循环节的代码
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; const long long mod=1000000007; int main() { long long i,a,b,c; a=1,b=0; for(i=1;;i++) { c=(3*a+b)%mod; b=a; a=c; if(a==1&&b==0) { cout<<i<<endl; break; } } return 0; }最内层的循环节在这里求出I之后把MOD
HDU 3483
http://acm.hdu.edu.cn/showproblem.php?pid=3483
构造矩阵十分巧妙。
![](http://acm.hdu.edu.cn/data/images/C295-1006-1.jpg)
就是求那货。。。
已知N x M
又是求和的式子,前面已经做到过好几次了,所以这一次不出意外肯定是把sn放到最后然后通过一个矩阵变成sn+1的形式了
然后再写一写有:sn+1=sn+(n+1)^x*x^n+1
首先再次感谢大湿原来给我出过一道
n
Σi^50 的题目,这道题目教会我再求i^k--->(i+1)^k的过程中,我们可以讲(i+1)^k二项展开来构造矩阵
i=0
所以这道题一开始的思路也是这样,把(n+1)^x顺势二项展开得到了一个式子,但是在x^n+1那里又被卡住了2天,最后大湿提醒我说x是已知的,可以提个x出来放进二项展开的
式子中去,终于恍然大悟,遂构造了(x+2)*(x+2)阶的矩阵进行求解,然后过了。。
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; long long n,x,mod; struct juzhen{ long long m[55][55]; }; juzhen mut(juzhen a,juzhen b) { juzhen c; for(long long i=0;i<x+2;i++) { for(long long j=0;j<x+2;j++) { c.m[i][j]=0; for(long long k=0;k<x+2;k++) { c.m[i][j]+=(a.m[i][k]*b.m[k][j])%mod; c.m[i][j]%=mod; } } } return c; } juzhen pow(juzhen a,long long p) { juzhen ans; memset(ans.m,0,sizeof(ans.m)); for(long long i=0;i<x+2;i++) { ans.m[i][i]=1; } while(p) { if(p%2==0) { a=mut(a,a); p/=2; } else { ans=mut(ans,a); p--; } } return ans; } int main() { while(cin>>n>>x>>mod) { if(n==-1&&x==-1&&mod==-1) return 0; juzhen ans; memset(ans.m,0,sizeof(ans.m)); for(long long i=0;i<x+1;i++) { ans.m[i][0]=ans.m[i][i]=x; } for(long long i=2;i<x+1;i++) { for (long long j=1;j<i;j++) { ans.m[i][j] =(ans.m[i-1][j-1] + ans.m[i-1][j])%mod; } } for(int i=0;i<x+1;i++) { ans.m[x+1][i]=ans.m[x][i]; } ans.m[x+1][x+1]=1; /* for(long long i=0;i<x+1;i++) { for(long long j=0;j<x+1;j++) { cout<<ans.m[i][j]<<" "; } cout<<endl; }*/ ans=pow(ans,n-1); long long sum=0; for(int i=0;i<x+2;i++) { sum+=(ans.m[x+1][i]*x)%mod; sum%=mod; } cout<<sum<<endl; } return 0; }
矩阵专题到此暂时告一段落了。。。刷了这些题,不知道有没有什么很大的用处,可能也就是把自己的大脑适当的开发了一下吧。。但是开发了一下总比让大脑生锈强,即使再笨,笨鸟也能先飞,只要努力,也许就可以跟那些动脑多的,厉害的人的差距变小一点点了吧。。。。
相关文章推荐
- [个人记录]半月板撕裂及SLAP损伤
- 查询表达式理解
- 回调函数
- 机器学习知识列表
- c# hashTable的遍历【2种方法】与排序【3种方法】
- JavaScript在页面显示当前时间的几种方法
- 永不锁屏
- WinCE Network驱动开发简介
- built-in.o ?
- Android SDK Manager更新不了的解决方法
- 读文本显示在scrollview(BFDeclareVController)
- DialogFragment简单的使用方法
- Plus One
- 数据分析软件Excel,Origin, Matlab,Mathmatica和Maple
- Session与Cookie详解
- 电脑自动关机是什么原因
- ARM的虚拟化原理
- TCP连接的实质
- 一年之计在于春,一日之计在于晨, 一生之计在于勤,清晨起来修手机
- C++学习札记20140325