2016ACM/ICPC亚洲区沈阳站(区域赛练习)(C 矩阵快速幂)

A - Thickest Burger

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int a,b;
		cin>>a>>b;
		cout<<2*max(a,b)+min(a,b)<<endl;
	}
	return 0;
}

B - Relative atomic mass

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	char ss[15];
	cin>>n;
	getchar();
	while(n--)
	{
		cin>>ss;
		int len=strlen(ss);
		int cnth=0;
		int cntc=0;
		int cnto=0;
		int sum=0;
		for(int i=0;i<len;i++)
		{
			if(ss[i]=='H')
			   cnth++;
			else if(ss[i]=='C')
			   cntc++;
			if(ss[i]=='O')
			   cnto++;
		}
		sum=cnth*1+cntc*12+cnto*16;
		cout<<sum<<endl;
	}
	return 0;
}

C Recursive sequence

知识点:矩阵快速幂

参考

1.根据题目描述,我们可以分析出:F(n) = F(n-1) + 2F(n-2) + n^4  并且F(1) = a , F(2) = b,求F(n)%2147493647,其中a、b、n是待输入的参数。

2.才刚开始接触矩阵快速幂,首先去学习什么是矩阵快速幂?

    2.1矩阵快速幂介绍:

         矩阵的快速幂运算,其实思路和整数快速幂是一样的。比如求矩阵A^7,本来是要求8次,我们先求出A^2,然后以A^2为基         础,这样求4次即可.(矩阵快速幂之所以称之为矩阵快速幂,说白了就是对矩阵进行快速幂的运算)

  2.2 矩阵快速幂求解步骤:

       2.2.1. 把非线性递推式转化为线性递推式
      2.2.2. 根据线性递推式得到F(n)和F(n+1)的矩阵序列
      2.2.3. 根据F(n)和F(n+1)的矩阵序列得到中间的转移矩阵
      2.2.4. 根据转移矩阵编写代码

3.针对本来来说:

   3.1把非线性递推式转化为线性递推式:

        F(n+1) = F(n) + 2F(n-1) + n^4 + 4n^3 + 6n^2 + 4n + n^0

    3.2根据线性递推式得到F(n)和F(n+1)的矩阵序列

   

2016ACM/ICPC亚洲区沈阳站(区域赛练习)(C 矩阵快速幂)

      补充一下矩阵相乘的原则:只有当A矩阵的行数等于B矩阵的列数的时候,才可以做乘法运算。并且:A(的列)*B(的行)

   3.3 根据F(n)和F(n+1)的矩阵序列得到中间的转移矩阵

       有了第二步的基础,那么我们现在就可以来推算转移矩阵[A]了,所求转移矩阵为:

long long num[7][7] =     {1, 2, 1, 4, 6, 4, 1,
                                   1, 0, 0, 0, 0, 0, 0,
                                   0, 0, 1, 4, 6, 4, 1,
                                   0, 0, 0, 1, 3, 3, 1,
                                   0, 0, 0, 0, 1, 2, 1,
                                   0, 0, 0, 0, 0, 1, 1,
                                   0, 0, 0, 0, 0, 0, 1};

f1=a;f2=b;f3= 2a + b + 2^4 + 4×2^3 + 6×2^2 + 4×2^1 + 2^0;

最后可以发现:B2 × An-2 = Bn(fn)(时间仓促,未整理完,日后待补。。。。)

#include<bits/stdc++.h> 
using namespace std;
#define mod 2147493647
int t;
int N,a,b;
void init(long long num[][7])
{
	for(int i=0;i<7;i++)
	{
		for(int j=0;j<7;j++)
		{
			if(i==j)
			   num[i][j]=1;
			else num[i][j]=0;
		}
	}
}
void cheng(long long (&aa)[7][7], long long bb[7][7])
{
	long long ans[7][7]={0};
	for(int i=0;i<7;i++)
	{
		for(int j=0;j<7;j++)
		{
			for(int k=0;k<7;k++)
			{
				ans[i][j]=(ans[i][j]+aa[i][k]*bb[k][j])%mod;
			}
		}
	}
	for(int i=0;i<7;i++)
	{
		for(int j=0;j<7;j++)
		{
			aa[i][j]=ans[i][j];
		}
	}
}

int main()
{
	long long center[7][7];//单位矩阵 
	cin>>t;
	while(t--)
	{
		scanf("%d%d%d",&N,&a,&b);
		if(N==1)
		{
			cout<<a<<endl;
			continue;
		}
	    long long num[7][7] = {1, 2, 1, 4, 6, 4, 1,
                                   1, 0, 0, 0, 0, 0, 0,
                                   0, 0, 1, 4, 6, 4, 1,
                                   0, 0, 0, 1, 3, 3, 1,
                                   0, 0, 0, 0, 1, 2, 1,
                                   0, 0, 0, 0, 0, 1, 1,
                                   0, 0, 0, 0, 0, 0, 1};
        init(center); 
        N=N-2;
        while(N)
        {
        	if(N&1) cheng(center,num);
        	cheng(num,num);
        	N=N/2;
		}
        long long int sum=0;
        sum=(sum+b*center[0][0])%mod;
        sum=(sum+a*center[0][1])%mod;
        sum=(sum+16*center[0][2])%mod;
        sum=(sum+8*center[0][3])%mod;
        sum=(sum+4*center[0][4])%mod;
        sum=(sum+2*center[0][5])%mod;
        sum=(sum+center[0][6])%mod;
        printf("%d\n",sum);
	}
	return 0;
}