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;
}
最后公式真的打吐了,早知道直接组合数了,造孽啊,给个免费的赞再走吧
┭┮﹏┭┮