首页 > 编程语言 >2022合肥学院acm程序设计大赛-热身赛题解 (1)

2022合肥学院acm程序设计大赛-热身赛题解 (1)

时间:2022-12-03 21:13:43浏览次数:66  
标签:Matrix int 题解 矩阵 long base acm 2022 mod

A.codeforces

直接读入输入即可

#include <bits/stdc++.h>
int main()
{
    string s;
    cin>>s;
    cout<<"https://codeforces.com/profile/"<<s;
    return 0;
}

B.小美挑糖果

对给定的所有糖果按数量进行排序,然后取最大的前\(k\)袋糖果。

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,k;
int a[N];
int main()
{
    cin>>n>>k;
    int ans=0;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    sort(a+1,a+1+n);
    for(int i=n;k;i--,k--)
        ans+=a[i];
    cout<<ans<<endl;
    return 0;
}

C.你好 ACM!

直接输出即可,但是需要注意反斜杠需要进行转义,例如

printf("\\");

输出为:
img

#include <bits/stdc++.h>
using namespace std;
int main()
{
    cout << " _    _          _   _                         _____   __  __   _" << endl;
    cout << "| |  | |        | | | |               /\\      / ____| |  \\/  | | |" << endl;
    cout << "| |__| |   ___  | | | |   ___        /  \\    | |      | \\  / | | |" << endl;
    cout << "|  __  |  / _ \\ | | | |  / _ \\      / /\\ \\   | |      | |\\/| | | |" << endl;
    cout << "| |  | | |  __/ | | | | | (_) |    / ____ \\  | |____  | |  | | |_|" << endl;
    cout << "|_|  |_|  \\___| |_| |_|  \\___/    /_/    \\_\\  \\_____| |_|  |_| (_)" << endl;
    return 0;
}

或者奇妙的PHP语言

 _    _          _   _                         _____   __  __   _ 
| |  | |        | | | |               /\      / ____| |  \/  | | |
| |__| |   ___  | | | |   ___        /  \    | |      | \  / | | |
|  __  |  / _ \ | | | |  / _ \      / /\ \   | |      | |\/| | | |
| |  | | |  __/ | | | | | (_) |    / ____ \  | |____  | |  | | |_|
|_|  |_|  \___| |_| |_|  \___/    /_/    \_\  \_____| |_|  |_| (_)

又或者奇妙的C++ Raw string

#include <bits/stdc++.h>
using namespace std;
int main()
{
    cout<<R"( _    _          _   _                         _____   __  __   _ 
| |  | |        | | | |               /\      / ____| |  \/  | | |
| |__| |   ___  | | | |   ___        /  \    | |      | \  / | | |
|  __  |  / _ \ | | | |  / _ \      / /\ \   | |      | |\/| | | |
| |  | | |  __/ | | | | | (_) |    / ____ \  | |____  | |  | | |_|
|_|  |_|  \___| |_| |_|  \___/    /_/    \_\  \_____| |_|  |_| (_))"<<endl;
    return 0;
}

D 奇怪的数列

解法1

平方和求和公式
\(\sum_{i=1}^{n}i^{2}=\frac{n(n+1)(2n+1)}{6}\)

证明:
\(i^{2}=i(i-1)+i\)

\(\sum_{i=1}^{n}i^{2}=\sum_{i=1}^{n}C_{i}^{1}+2*C_{i}^{2}=2*C_{n+1}^{3}+C_{n+1}^{2}=\frac{n(n+1)(2n+1)}{6}\)

直接套公式即可,注意数据范围很大,需要开\(long\ long\)并在每次乘法操作后取模,防止超出\(long\ long\)的范围。

对于取模操作,\(\frac{a}{b}mod\ N\ne \frac{a\ mod\ N}{b\ mod\ N}\)。

但是如果变成乘法,\(a*\frac{1}{b}\ mod\ N=\frac{a}{b}mod\ N\)。

所以我们需要求\(\frac{1}{b}\),即\(b\)的逆元

求逆元一定要满足\(a\)与\(mod\)互质。题目给出的模数\(10^{9}+7\)是质数,所以一定满足互质的条件。

#include <bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
long long qmi(long long a, long long b, long long mod)//快速幂求6的逆元
{
    long long res = 1;
    while (b)
    {
        if (b & 1)
            res = res * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return res;
}
int main()
{
    long long n;
    cin>>n;
    cout<<((n%mod)*((n+1)%mod))%mod*(2*n%mod+1)%mod*qmi(6,mod-2,mod)%mod;
    return 0;
}

解法2

比较典型的矩阵快速幂模板题。正常的线性递推求解的方法由于1e18的时间范围限制,
在时间复杂度上肯定是过不去的,所以本题我们考虑使用矩阵快速幂来求解。

先分析递推式:\(a_n = a_{n - 1} + n^2\)
这里为了构造第\(n\)项矩阵的通式,我们可以看出,第\(n\)项目前应该获取的值有\(a_n\)和\(n^2\)
同时还要获得前一项的值\(a_{n-1}\)和\((n-1)^2\)。

这里通过平方差公式,我们可以得到\(n^2=(n-1)^2+2n-1\)
所以除了上述信息,我们的第\(n\)项还需要获取\(n\)的值
通过这些信息,我们可以设第\(n\)项矩阵为:

\[\left\{\begin{matrix}a_n&n^2&n&1\end{matrix}\right\} \]

相应的,第\(n-1\)项矩阵应

\[\left\{\begin{matrix}a_{n-1}&(n-1)^2&n-1&1\end{matrix}\right\} \]

处理到这里,我们得到了第\(n-1\)项矩阵和第\(n\)项矩阵,而我们还需要最后一个\(base\)矩阵,构造出矩阵的乘法恒等式。学习过线性代数的知识后,通过矩阵的乘法规则,我们可以构造出

\(base\)=

\[\left\{\begin{matrix}1 & 0 & 0 & 0 \\1 & 1 & 0 & 0 \\2 & 2 & 1 & 0 \\1 & 1 & 1 & 1 \\\end{matrix}\right\} \]

这里我们可以得到恒等式:\(Matrix(a_n)=Matrix(a_{n-1})*base\)


写到这里,我们的原式就转化为了矩阵乘法的递推式,而我们的初始矩阵\(Matrix(a_0)\)可以从题面中直接获取,即\(\left\{\begin{matrix}0 & 0 & 0 & 1\end{matrix}\right\}\)
通过矩阵的乘法结合律我们将恒等式进一步优化为:
\(Matrix(a_n)(n>0)=Matrix(a_0)*\prod_{i=1}^{n}base\)
累乘这一部分的时间复杂度我们就可以使用矩阵快速幂的模板来将原本的时间复杂度由\(O(n)\)降到\(O(logn)\)级别。

#include<bits/stdc++.h>
using namespace std;

#define LL long long
const LL mod = 1e9 + 7;
const int N = 10;

struct Matrix {
    LL m[11][11];
};

LL n;
Matrix base, res;

Matrix Mul(Matrix x, Matrix y) {
    Matrix c;
    for (int i = 0; i < N; i ++ ) 
        for (int j = 0; j < N; j ++ ) c.m[i][j] = 0;
    for(int i = 0; i < N; i ++ )
        for(int j = 0; j < N; j ++ )
            for(int k = 0; k < N; k ++ )
                c.m[i][j] = c.m[i][j] % mod + x.m[i][k] * y.m[k][j] % mod;
    return c;
}

Matrix pow(Matrix x, LL y) {
    Matrix ans = x;
    while(y) {
        if(y & 1) ans = Mul(ans, x);
        x = Mul(x, x);
        y >>=1 ;
    }
    return ans;
}



void init() { 
	base.m[0][0] = 1; base.m[0][1] = 0; base.m[0][2] = 0; base.m[0][3] = 0; 
	base.m[1][0] = 1; base.m[1][1] = 1; base.m[1][2] = 0; base.m[1][3] = 0; 
	base.m[2][0] = 2; base.m[2][1] = 2; base.m[2][2] = 1; base.m[2][3] = 0; 
	base.m[3][0] = 1; base.m[3][1] = 1; base.m[3][2] = 1; base.m[3][3] = 1; 
	res.m[0][3] = 1;
}

int main() {
	cin >> n;
	if (!n) {
		cout << 0 << endl;
		return 0;
	}
	init();
	res = Mul(res, pow(base, n - 1));
	cout << res.m[0][0] << endl;
	return 0;
}

标签:Matrix,int,题解,矩阵,long,base,acm,2022,mod
From: https://www.cnblogs.com/Chesedss/p/16948768.html

相关文章