2021 CCPC 网络重赛题解
1004
思路
定义\(f(x)\)为大于\(x\)的最小素数,定义\(g(x)=\left\lfloor\frac{f(x)+f(f(x))}{2}\right\rfloor\),如果\(g(x)\)是素数输出YES,否则输出NO
注意到\(f(x)\)与\(f(f(x))\)是两个不同的素数,而当\(x>2\)时两个素数取整后的均值介于两者之间,不可能为素数,因此唯一的特殊情况为当\(x=1\)时,\(f(x)=2\),\(f(f(x))=3\),此时\(g(x)\)为素数,输出YES,其它情况输出NO即可
代码
#include<bits/stdc++.h>
#define LL long long
using namespace std;
int main(){
int T;
cin>>T;
while(T--){
LL tmp;
cin>>tmp;
if(tmp == 1) printf("Yes\n");
else printf("No\n");
}
}
1006
大致的题意为
给一个字符串,要求满足下列条件的字串个数:
- 能够被分为两部分
- 第一部分为
nunehhe
- 第二部分为个数大于一个的a的连续字串
思路
对于每一个位置,分为前缀部分和后缀部分求解,我们这里主要关心前缀部分的最后一个位置也就是字母h
。我们对于输入字符串从前往后遍历,每遍历到一个可能的前缀结尾,便对这个状态进行计数,将答案加上 前缀可能数✖后缀可能数 个,良好预处理之后的时间复杂度为O(n),刚好通过。
后缀可能数很好维护,直接维护一个a的后缀和数组,计算通过快速幂计算组合数后减一就行了。
前缀可能数其实也很简单。我们通过以下形式维护:
记当前位置下,前缀和第i个位置为结尾的截取字串的前缀可能数为a[i]
则有
if (输入字符串遍历的当前位置与前缀部分第i个位置匹配): a[i] += a[i-1]
其实就是更新以当前位置的字符为结尾的亚前缀可能数,以一种类似动态规划的方法进行迭代维护。
而答案记录就是:
if(当前位置字符==h) ans += a[8] * (快速幂(2, 后缀数组[i]) - 1)
代码
#include <bits/stdc++.h>
using namespace std;
string s;
int n;
const int maxn = 1000005;
long long s_cnt[10];
long long mod = 998244353;
long long hz[maxn];
long long ans;
long long qpow(long long k) {
long long res = 1;
long long x = 2;
while (k != 0) {
if (k & 1) res = (res * x)%mod;
x = (x * x) % mod;
k /= 2;
}
return res;
}
int main() {
cin >> n;
while (n--) {
for (int i = 0; i < 10; i++) {
s_cnt[i] = 0;
}
for (int i = 0; i < maxn; i++) {
hz[i] = 0;
}
cin >> s;
ans = 0;
auto len = (long long)s.length();
for (long long i = len - 1; i >= 0; i--) {
hz[i] = hz[i + 1];
if (s[i] == 'a') {
hz[i] = hz[i] + 1 % mod;
}
}
for (int i = 0; i < len; i++) {
if (s[i] == 'n') {
s_cnt[3] = s_cnt[3] + s_cnt[2] % mod;
s_cnt[1] = s_cnt[1] + 1 % mod;
}
if (s[i] == 'u') {
s_cnt[2] = s_cnt[2] + s_cnt[1] % mod;
}
if (s[i] == 'e') {
s_cnt[5] = s_cnt[5] + s_cnt[4] % mod;
s_cnt[8] = s_cnt[8] + s_cnt[7] % mod;
}
if (s[i] == 'h') {
s_cnt[4] = s_cnt[4] + s_cnt[3] % mod;
s_cnt[7] = s_cnt[7] + s_cnt[6] % mod;
s_cnt[6] = s_cnt[6] + s_cnt[5] % mod;
s_cnt[9] = s_cnt[9] + s_cnt[8] % mod;
ans += ((qpow(hz[i]) - 1) * s_cnt[8]) % mod;
ans %= mod;
}
}
if(n==0) printf("%lld",ans);
else printf("%lld\n",ans);
}
}