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);
}
}