F:
题目传送门
题目翻译:
给你一个 o
和 x
构成的字符串
S
S
S,把把恰好
k
k
k 个
x
x
x 改成 o
执行
M
M
M 遍之后,使得最长连续全 o
子串最长,计算这个长度。
题目思路:
首先你得把
k
k
k 取模,然后二分
r
r
r 即可。注意要用 upper_bound
。 upper_bound
才能和原来就有的 o
拼接起来。普通遍历的话会超时
代码:
#include <bits/stdc++.h>
using namespace std;
int main(){
int N, M;
long long K;
cin >> N >> M >> K;
string S;
cin >> S;
vector<int> p;
for (int i = 0; i < N; i++){
if (S[i] == 'x'){
p.push_back(i);
}
}
int cnt = p.size();
long long x = (long long) M * cnt;
if (x == K){
cout << (long long) N * M << endl;
} else {
long long ans = 0;
ans = max(ans, p[K % cnt] + (long long) N * (K / cnt));
ans = max(ans, N - 1 - p[cnt - 1 - K % cnt] + (long long) N * (K / cnt));
for (int i = 0; i < cnt; i++){
if (i + K + 1 < x){
ans = max(ans, p[(i + K + 1) % cnt] + (long long) N * ((i + K + 1) / cnt) - p[i] - 1);
}
}
cout << ans << endl;
}
}
G:
题目传送门
题目大意:
给你两个数 n 和 p,问有多少个数
1
≤
x
≤
n
1≤x≤n
1≤x≤n 它的质因子都小于等于
p
p
p,保证
p
p
p 为质数。
题目思路:
装换一下题意,可以改变成枚举
1
1
1 到
p
p
p 中的质数的指数,并使得最终乘积小于等于
n
n
n。
考虑二分搜索,我们将
1
1
1 到
p
p
p 中的质数分为两半,先计算前一半能达到的数的情况,然后再枚举后半段的情况,看前半段有多少个质数和后半段的乘积小于等于
n
n
n,对于所有这样的情况求和即可。
题目代码:
#include <bits/stdc++.h>
using namespace std;
int main(){
long long N;
int P;
cin >> N >> P;
vector<int> p;
for (int i = 2; i <= P; i++){
bool ok = true;
for (int j = 2; j < i; j++){
if (i % j == 0){
ok = false;
}
}
if (ok){
p.push_back(i);
}
}
auto solve = [&](vector<int> p2){
int cnt = p2.size();
vector<long long> ans;
auto dfs = [&](auto dfs, long long n, int i) -> void {
if (i == cnt){
ans.push_back(n);
} else {
while (true){
dfs(dfs, n, i + 1);
if (n <= N / p2[i]){
n *= p2[i];
} else {
break;
}
}
}
};
dfs(dfs, 1, 0);
return ans;
};
int m = min(8, (int) p.size());
vector<int> p2(p.begin(), p.begin() + m), p3(p.begin() + m, p.end());
vector<long long> A = solve(p2), B = solve(p3);
int N1 = A.size(), N2 = B.size();
sort(A.begin(), A.end());
sort(B.begin(), B.end());
long long ans = 0;
for (int i = 0; i < N1; i++){
ans += upper_bound(B.begin(), B.end(), N / A[i]) - B.begin();
}
cout << ans << endl;
}
Ex
代码:
#include <bits/stdc++.h>
#include <atcoder/convolution>
using namespace std;
const long long MOD = 998244353;
int main(){
int K;
long long N;
cin >> K >> N;
vector<long long> P(K + 1, 0), Q(K + 1, 0);
for (int i = 0; i < K; i++){
P[i] = (1 - i + MOD) % MOD;
}
Q[0] = 1;
for (int i = 1; i <= K; i++){
Q[i] = MOD - 1;
}
while (N > 0){
if (N % 2 == 1){
P = atcoder::convolution(P, {1, 1});
Q = atcoder::convolution(Q, {1, 0});
K++;
}
vector<long long> Q2 = Q;
for (int i = 1; i <= K; i += 2){
Q2[i] = (MOD - Q2[i]) % MOD;
}
P = atcoder::convolution(P, Q2);
Q = atcoder::convolution(Q, Q2);
vector<long long> Ue(K + 1, 0), Uo(K + 1, 0), V(K + 1, 0);
for (int i = 0; i <= K; i++){
Ue[i] = P[i * 2];
if (i < K){
Uo[i] = P[i * 2 + 1];
}
V[i] = Q[i * 2];
}
if (N % 2 == 1){
P = Uo;
} else {
P = Ue;
}
Q = V;
N /= 2;
}
cout << P[0] << endl;
}