zoukankan      html  css  js  c++  java
  • A Simple Math Problem

    Lele now is thinking about a simple function f(x).

    If x < 10 f(x) = x. If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2* f(x-3) + …… + a9 * f(x-10); And ai(0<=i<=9) can only be 0 or 1 .

    Now, I will give a0 ~ a9 and two positive integers k and m ,and could
    you help Lele to caculate f(k)%m.

    Input
    The problem contains mutiple test cases.Please process to the end of file.
    In each case, there will be two lines.
    In the first line , there are two positive integers k and m. ( k<2*10^9 , m < 10^5 )
    In the second line , there are ten integers represent a0 ~ a9.
    Output
    For each case, output f(k) % m in one line.
    Sample Input
    10 9999
    1 1 1 1 1 1 1 1 1 1
    20 500
    1 0 1 0 1 0 1 0 1 0
    Sample Output
    45
    104

    题目大意:
    If x < 10 f(x) = x.
    If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
    And ai(0<=i<=9) can only be 0 or 1 .
    利用公式求出f(k) % m并输出。注意 k<2*10^9 , m < 10^5.

    解题思路:利用矩阵快速幂进行求解,重点在于怎样构造矩阵。
    在这里插入图片描述
    利用矩阵快速幂所求第一行即是答案。
    node ans=a^(n-9)*b;

    Code:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int m;
    ll k;
    
    struct node {
    	ll materix[50][50];
    };
    node a,b;
    
    node mul(node a,node b){//矩阵乘法
    	node ans;
    	memset(ans.materix,0,sizeof(ans.materix));
    	for(int i=1;i<=10;i++){
    		for(int j=1;j<=10;j++){
    			for(int k=1;k<=10;k++){
    				ans.materix[i][j]=(ans.materix[i][j]+a.materix[i][k]*b.materix[k][j]%m)%m;
    			}
    		}
    	}
    	return ans;
    }
    
    node ksm(node a,ll b){//矩阵快速幂
    	node ans;
    	memset(ans.materix,0,sizeof(ans.materix));
    	for(int i=1;i<=10;i++) ans.materix[i][i]=1;
    	while(b){
    		if(b&1) ans=mul(ans,a);
    		a=mul(a,a);
    		b>>=1;
    	}
    	return ans;
    	
    }
    
    int main(){
    	while(cin>>k>>m){
    		memset(a.materix,0,sizeof(a.materix));
    		for(int i=1;i<=10;i++){
    			cin>>a.materix[i][1];
    		}
    		for(int i=1;i<=10;i++){
    			a.materix[i][i+1]=1;
    		}
    		if(k<10){
    			cout<<k%m<<endl;
    			continue;
    		}
    		else {
    			node b;
    			for(int i=1;i<=10;i++){
    				b.materix[1][i]=10-i;
    			}
    			node ans=ksm(a,k-9);
    			ans=mul(b,ans);
    			cout<<ans.materix[1][1]%m<<endl;
    		}
    	}
    	return 0;
    }
    
    七月在野,八月在宇,九月在户,十月蟋蟀入我床下
  • 相关阅读:
    centos ppp拨号
    Xen、KVM和VirtualBox比拼
    static用法一
    linux浏览器,邮件客户端,输入法,双屏设置,应用软件,gnome-screenshot/scrot -s截图,office
    OpenGl学习总结
    DICOM医学图像处理:DCMTK在VS2012中的配置
    linux下用mail发送邮件
    (HLS播放器之中的一个)HLS协议之M3U8解析
    tcpdump抓包分析具体解释
    对账简单说
  • 原文地址:https://www.cnblogs.com/voids5/p/12695038.html
Copyright © 2011-2022 走看看