牛客挑战赛73题解(A~C)

A. S老师的公式

在这里插入图片描述
代码如下

#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N=1e5+10;
int n,m,a[N];
void solve()
{
	cin>>n;
    int x=0,y=1;
	for(int i=1;i<=n;i++) x+=i;//先算出所有的和,即n(n+1)/2
    for(int i=1;i<=n;i++) y=y*i%x;//因为gcd往下递归是从gcd(a,b)->gcd(b,a%b);
    cout<<__gcd(x,y)<<endl;		  //所以这里乘上一个数每次取模就可以了
}
signed main()
{
	ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
	int T=1;
//	cin>>T;
	while(T--)
	{
		solve();
	}
	return 0;
}

B. S老师的签到

在这里插入图片描述
从左上角走到右下角,很经典的dp
相似题目:AcWing 1018. 最低通行费
状态表示:f [ i ][ j ]:走到 ( i,j ) 时,所用的最小花费
姑且将按照字典序最小当成最小花费吧,把每一个字母看成相应ASCLL值就行了
状态转移方程:f [ i ][ j ] = min ( f [ i - 1 ][ j ],f [ i ][ j - 1 ] ) + s [ i ][ j ]
我们这里每一个 f [ i ][ j ] 直接存相应字符串就行,比较也是这样比较,会自动按照对应ASCLL值比较的
那这样子的话就会用到string存储,开一个二维数组:
string f[N][N],这里N=1e3+50 > 210=1024

在这里插入图片描述
就样例来看,上面是对应位置的存储,但是当n=m=210时,很显然,越往后面所要花费的空间越多,因为字符串会越来越长,用的字节就越来越多,显然这样子是有大概率会MLE的
在这里插入图片描述

那这里其实可以优化掉一维,我们注意到,只需要预处理出第一行的字符串,那么往下处理的时候,每次都可以用到上一行的值,也就是向下的箭头已经成立,向右的箭头,可以在 f [ 1 ] 的位置上直接加上 s [ 2 ][ 1 ],成为改变后的 f [ 1 ],
这样子 f [ 2 ] = min( f [ 1 ] ,f [ 2 ])+ s [ 2 ][ 2 ],f [ 2 ] 从上一行更新为了这一行的值,随后 f [ 3 ] = min( f [ 2 ],f [ 3 ])+s [ 2 ][ 3],向右箭头已经成立

#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N=1e3+50;
int n,m;
char s[N][N];
string f[N];//当前行第j列的值
void solve()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>s[i][j];//1~n和1~m存储
    f[1]=s[1][1];//第一行第一列
    for(int i=2;i<=m;i++)//更新第一行2~m列的值
        f[i]=f[i-1]+s[1][i];
    for(int i=2;i<=n;i++)//从第二行开始
    {
        f[1]+=s[i][1];//第一列其实和第一行一样,每次直接加就行了(第i行,第1列)
        for(int j=2;j<=m;j++)//第i行,第j列
        {
            f[j]=min(f[j-1],f[j])+s[i][j];
        }
    }
    cout<<f[m];//输出第m列的值(当前已经是第n行了)
}
signed main()
{
	ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
	int T=1;
//	cin>>T;
	while(T--)
	{
		solve();
	}
	return 0;
}

C. S老师的求和

在这里插入图片描述
这里求和可以直接用组合数算,如下链接性质10即为所用
来自GhostLX的组合数学基础
每次都可以将求和,用如下公式更新:
在这里插入图片描述
但是,不知道公式该怎么办呢?,如下:

首先,L1(k) = ak+b ,已经达到了可以直接输出的程度

L2(k)

= ∑ i = 1 k L 1 ( i ) \sum_{i=1}^{k} L_1(i) i=1kL1(i)

= ∑ i = 1 k ( a i + b ) \sum_{i=1}^{k} (ai+b) i=1k(ai+b)

= ∑ i = 1 k a i + ∑ i = 1 k b \sum_{i=1}^{k} ai +\sum_{i=1}^{k}b i=1kai+i=1kb

= ( 1 + 2 + . . . + k ) a + k b (1+2+...+k)a+kb (1+2+...+k)a+kb

= k ( k + 1 ) 2 a + k b \frac{k(k+1)}{2}a+kb 2k(k+1)a+kb

至此,L2(k) = k ( k + 1 ) 2 a + k b \frac{k(k+1)}{2}a+kb 2k(k+1)a+kb,可以直接输出

L3(k)

= ∑ i = 1 k L 2 ( i ) \sum_{i=1}^{k}L_2(i) i=1kL2(i)

= ∑ i = 1 k [ k ( k + 1 ) 2 a + k b ] \sum_{i=1}^{k} [\frac{k(k+1)}{2}a+kb] i=1k[2k(k+1)a+kb]

= ∑ i = 1 k ( k 2 2 + k 2 ) a + ∑ i = 1 k k b \sum_{i=1}^{k}(\frac{k^2}{2}+\frac{k}{2})a+\sum_{i=1}^{k}kb i=1k(2k2+2k)a+i=1kkb

= ∑ i = 1 k k 2 2 a + ∑ i = 1 k k 2 a + ∑ i = 1 k k b \sum_{i=1}^{k}\frac{k^2}{2}a+\sum_{i=1}^{k}\frac{k}{2}a+\sum_{i=1}^{k}kb i=1k2k2a+i=1k2ka+i=1kkb

= 1 2 ( 1 2 + 2 2 + . . . + k 2 ) a + 1 2 ( 1 + 2 + . . . + k ) a + ( 1 + 2 + . . + k ) b \frac{1}{2}(1^2+2^2+...+k^2)a+\frac{1}{2}(1+2+...+k)a+(1+2+..+k)b 21(12+22+...+k2)a+21(1+2+...+k)a+(1+2+..+k)b

= k ( k + 1 ) ( 2 k + 1 ) 12 a + k ( k + 1 ) 4 a + k ( k + 1 ) 2 b \frac{k(k+1)(2k+1)}{12}a+\frac{k(k+1)}{4}a+\frac{k(k+1)}{2}b 12k(k+1)(2k+1)a+4k(k+1)a+2k(k+1)b

至此,L3(k) = k ( k + 1 ) ( 2 k + 1 ) 12 a + k ( k + 1 ) 4 a + k ( k + 1 ) 2 b \frac{k(k+1)(2k+1)}{12}a+\frac{k(k+1)}{4}a+\frac{k(k+1)}{2}b 12k(k+1)(2k+1)a+4k(k+1)a+2k(k+1)b,可以直接输出

L4(k)

= ∑ i = 1 k L 3 ( i ) \sum_{i=1}^{k}L_3(i) i=1kL3(i)

= ∑ i = 1 k [ k ( k + 1 ) ( 2 k + 1 ) 12 a + k ( k + 1 ) 4 a + k ( k + 1 ) 2 b ] \sum_{i=1}^{k}[\frac{k(k+1)(2k+1)}{12}a+\frac{k(k+1)}{4}a+\frac{k(k+1)}{2}b] i=1k[12k(k+1)(2k+1)a+4k(k+1)a+2k(k+1)b]

= ∑ i = 1 k ( 2 k 3 + 3 k 2 + k 12 a + k 2 + k 4 a + k 2 + k 2 b ) \sum_{i=1}^{k}(\frac{2k^3+3k^2+k}{12}a+\frac{k^2+k}{4}a+\frac{k^2+k}{2}b) i=1k(122k3+3k2+ka+4k2+ka+2k2+kb)

= ∑ i = 1 k [ ( k 3 6 + k 2 2 + k 3 ) a + ( k 2 2 + k 2 ) b ] \sum_{i=1}^{k}[(\frac{k^3}{6}+\frac{k^2}{2}+\frac{k}{3})a+(\frac{k^2}{2}+\frac{k}{2})b] i=1k[(6k3+2k2+3k)a+(2k2+2k)b]

= ∑ i = 1 k k 3 6 a + ∑ i = 1 k k 2 2 a + ∑ i = 1 k k 3 a + ∑ i = 1 k k 2 2 b + ∑ i = 1 k k 2 b \sum_{i=1}^{k}\frac{k^3}{6}a+\sum_{i=1}^{k}\frac{k^2}{2}a+\sum_{i=1}^{k}\frac{k}{3}a+\sum_{i=1}^{k}\frac{k^2}{2}b+\sum_{i=1}^{k}\frac{k}{2}b i=1k6k3a+i=1k2k2a+i=1k3ka+i=1k2k2b+i=1k2kb

= [ k ( k + 1 ) ] 2 24 a + k ( k + 1 ) ( 2 k + 1 ) 12 a + k ( k + 1 ) 6 a + k ( k + 1 ) ( 2 k + 1 ) 12 b + k ( k + 1 ) 4 b \frac{[k(k+1)]^2}{24}a+\frac{k(k+1)(2k+1)}{12}a+\frac{k(k+1)}{6}a+\frac{k(k+1)(2k+1)}{12}b+\frac{k(k+1)}{4}b 24[k(k+1)]2a+12k(k+1)(2k+1)a+6k(k+1)a+12k(k+1)(2k+1)b+4k(k+1)b

至此,
L4(k) = [ k ( k + 1 ) ] 2 24 a + k ( k + 1 ) ( 2 k + 1 ) 12 a + k ( k + 1 ) 6 a + k ( k + 1 ) ( 2 k + 1 ) 12 b + k ( k + 1 ) 4 b \frac{[k(k+1)]^2}{24}a+\frac{k(k+1)(2k+1)}{12}a+\frac{k(k+1)}{6}a+\frac{k(k+1)(2k+1)}{12}b+\frac{k(k+1)}{4}b 24[k(k+1)]2a+12k(k+1)(2k+1)a+6k(k+1)a+12k(k+1)(2k+1)b+4k(k+1)b,可以直接输出

代码如下:

#include<bits/stdc++.h>
#define int long long
#define endl "\n"
using namespace std;
const int N=1e5+10,mod=998244353;
int a,b,x;
int qmi(int a,int b)//除法->乘法逆元和指数运算都可以直接用快速幂
{
    int res=1;
    while(b)
    {
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
void solve()
{
	cin>>a>>b>>x;
	cout<<(a*x%mod+b)%mod<<' ';
    cout<<(a*x%mod*(x+1)%mod*qmi(2,mod-2)%mod+b*x%mod)%mod<<' ';
    cout<<(((x*(x+1)%mod*qmi(4,mod-2)%mod+x*(x+1)%mod*(2*x+1)%mod*qmi(12,mod-2)%mod)%mod*a%mod)+b*x%mod*(x+1)%mod*qmi(2,mod-2)%mod)%mod<<' ';
    cout<<(qmi(x*(x+1)%mod,2)*qmi(24,mod-2)%mod*a%mod+x*(x+1)%mod*(2*x+1)%mod*qmi(12,mod-2)%mod*a%mod+x*(x+1)%mod*qmi(6,mod-2)%mod*a%mod+x*(x+1)%mod*qmi(4,mod-2)%mod*b%mod+x*(x+1)%mod*(2*x+1)%mod*qmi(12,mod-2)%mod*b%mod)%mod;
}
signed main()
{
	ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
	int T=1;
	cin>>T;
	while(T--)
	{
		solve();
	}
	return 0;
}

最后公式真的打吐了,早知道直接组合数了,造孽啊,给个免费的赞再走吧
┭┮﹏┭┮

  • 27
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值