AtCoder Beginner Contest 171(补题)
Posted 佐鼬Jun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 171(补题)相关的知识,希望对你有一定的参考价值。
C - One Quadrillion and One Dalmatians
题意:
现在 1 到 26 1到26 1到26的数字为 a 到 z a到z a到z, 27 27 27到 702 702 702数字为 aa, ab, ac, …, zy, zz,475255,475256为aaaaa, aaaab,现在给你数字 n n n,让你输出对应的字符串
思路:
26个字母,所以转换为26进制,每次取余前,要减去1,把 [ 1 , 26 ] [1,26] [1,26]映射到 [ 0 , 25 ] [0,25] [0,25],然后输出即可
#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll n;
stack<int> sta;
int main() {
cin >> n;
while (n) {
n--;
sta.push(n % 26);
n /= 26;
}
while (!sta.empty()) {
int x = sta.top();
sta.pop();
printf("%c", x + 'a');
}
return 0;
}
F - Strivore
题意:
给一个长度为 m m m字符串,现在可以往字符串里加任意字符,可以加 n n n次,问最终会形成多少种字符串,答案对 1 0 9 + 7 10^9+7 109+7取模
思路:
组合数(排列组合)+去重+快速幂+逆元
加
n
n
n次字符,最终字符串长度是
n
+
m
n+m
n+m,现在先确定
s
s
s字符串的第一个字母的位置在
i
i
i号位置
(
1
<
=
i
<
=
n
+
1
)
(1<=i<=n+1)
(1<=i<=n+1),那么此时
i
i
i号位置前面的每个位置的字母情况都是26,所以就是
2
6
i
−
1
26^{i-1}
26i−1,
i
i
i后面的位置,先从后面的位置选出
s
s
s串剩下
m
−
1
m-1
m−1个字母的位置,由于相对顺序是固定的,所以是
C
n
+
m
−
i
m
−
1
C^{m-1}_{n+m-i}
Cn+m−im−1然后每个
s
s
s 串字母后面不选相同的字母,用于去重,所以是
2
5
n
+
m
−
i
−
m
+
1
25^{n+m-i-m+1}
25n+m−i−m+1,即
2
5
n
−
i
+
1
25^{n-i+1}
25n−i+1种情况,
小证明: 若有个
s
s
s字符串为
a
b
c
abc
abc
那么枚举位置
i
i
i的时候,会有这种情况, _____a()()()()b______c
如果a的第二个位置填了a,就是_____aa()()()b______c
那么下次枚举第一个字母a位置的位置,为下一个位置
i
+
1
i+1
i+1
也就是_____a()()()b______c
而此时这个a前面由于是26种情况
肯定会有_____aa()()()b______c
所以重复,这里枚举的是第二个位置,后面的位置同理如此
下面代码由于
i
i
i是从0开始循环到
n
n
n,所以公式有-1的差距
公式:
∑
i
=
0
n
\\sum \\limits_{i=0} ^{n}
i=0∑n
⋅
2
6
i
·26^{i}
⋅26i
⋅
C
n
+
m
−
i
−
1
m
−
1
·C^{m-1}_{n+m-i-1}
⋅Cn+m−i−1m−1
⋅
2
5
n
−
i
·25^{n-i}
⋅25n−i
#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int N = 1e6 + 10;
#define ll long long
string s;
int n;
ll fact[N*2], infact[N*2];
ll qmi(ll a, ll k, ll p) {
ll res = 1;
while (k) {
if (k & 1) res = (ll)res * a % p;
a = (ll)a * a % mod;
k >>= 1;
}
return res;
}
void init() {
fact[0] = infact[0] = 1;
for (int i = 1; i < 2*N; i++) {
fact[i] = (ll)fact[i - 1] * i % mod;
infact[i] = (ll)infact[i - 1] * qmi(i, mod - 2, mod) % mod;
}
}
ll C(int a, int b) { return fact[a] * infact[b] % mod * infact[a - b] % mod; }
int main() {
init();
cin >> n >> s;
ll res = 0;
int m = s.size();
for (int i = 0; i <= n; i++) {
res = (ll)res + qmi(26, i, mod) % mod * C(n + m - i - 1, m - 1) % mod *
qmi(25, n - i, mod) % mod;
}
cout << res % mod << endl;
}
To be continued
如果你有任何建议或者批评和补充,请留言指出,不胜感激
以上是关于AtCoder Beginner Contest 171(补题)的主要内容,如果未能解决你的问题,请参考以下文章
AtCoder Beginner Contest 115 题解