提出 #74308823
ソースコード 拡げる
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 100; // fib[100] > 1e18
string x, y;
int q, l1, l2;
int fib[MAXN];
int cnt[MAXN][30]; // cnt[n][c] = S_n中字符c的总数
// 预计算
void precompute() {
fib[1] = l1;
fib[2] = l2;
for (int i = 3; i < MAXN; i++) {
if (fib[i-1] > 2e18) {
fib[i] = 2e18;
} else {
fib[i] = fib[i-1] + fib[i-2];
}
}
// 计算S1
for (int c = 1; c <= 26; c++) cnt[1][c] = 0;
for (char ch : x) {
if (ch >= 'a' && ch <= 'z') {
cnt[1][ch - 'a' + 1]++;
}
}
// 计算S2
for (int c = 1; c <= 26; c++) cnt[2][c] = 0;
for (char ch : y) {
if (ch >= 'a' && ch <= 'z') {
cnt[2][ch - 'a' + 1]++;
}
}
for (int i = 3; i < MAXN; i++) {
for (int c = 1; c <= 26; c++) {
cnt[i][c] = cnt[i-1][c] + cnt[i-2][c];
}
}
}
// 优化的查询函数,避免重复计算
int query_optimized(int n, int len, int c) {
if (len <= 0) return 0;
int result = 0;
int cur_n = n;
int cur_len = len;
while (cur_len > 0 && cur_n > 2) {
if (cur_len <= fib[cur_n-1]) {
// 全部在S_{n-1}中
cur_n--;
} else {
// 包含S_{n-1}的全部
result += cnt[cur_n-1][c];
cur_len -= fib[cur_n-1];
cur_n -= 2;
}
}
// 处理S1或S2
if (cur_n == 1 && cur_len > 0) {
int l = min(cur_len, l1);
for (int i = 0; i < l; i++) {
if (x[i] - 'a' + 1 == c) result++;
}
} else if (cur_n == 2 && cur_len > 0) {
int l = min(cur_len, l2);
for (int i = 0; i < l; i++) {
if (y[i] - 'a' + 1 == c) result++;
}
}
return result;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> x >> y >> q;
l1 = x.size();
l2 = y.size();
precompute();
// 预计算S1和S2中每个位置的前缀字符计数
vector<vector<int>> pre1(l1+1, vector<int>(27, 0));
vector<vector<int>> pre2(l2+1, vector<int>(27, 0));
for (int i = 1; i <= l1; i++) {
for (int c = 1; c <= 26; c++) pre1[i][c] = pre1[i-1][c];
pre1[i][x[i-1] - 'a' + 1]++;
}
for (int i = 1; i <= l2; i++) {
for (int c = 1; c <= 26; c++) pre2[i][c] = pre2[i-1][c];
pre2[i][y[i-1] - 'a' + 1]++;
}
while (q--) {
int ql, qr;
char ch;
cin >> ql >> qr >> ch;
int c = ch - 'a' + 1;
// 找到n使得fib[n] >= qr
int n = 1;
while (n < MAXN && fib[n] < qr) n++;
if (n >= MAXN) n = MAXN - 1;
// 计算前缀和
int ans_r = 0, ans_l = 0;
// 计算[1, qr]
int cur_n = n, cur_len = qr;
while (cur_len > 0 && cur_n > 2) {
if (cur_len <= fib[cur_n-1]) {
cur_n--;
} else {
ans_r += cnt[cur_n-1][c];
cur_len -= fib[cur_n-1];
cur_n -= 2;
}
}
if (cur_n == 1 && cur_len > 0) {
ans_r += pre1[min(cur_len, l1)][c];
} else if (cur_n == 2 && cur_len > 0) {
ans_r += pre2[min(cur_len, l2)][c];
}
// 计算[1, ql-1]
cur_n = n; cur_len = ql - 1;
while (cur_len > 0 && cur_n > 2) {
if (cur_len <= fib[cur_n-1]) {
cur_n--;
} else {
ans_l += cnt[cur_n-1][c];
cur_len -= fib[cur_n-1];
cur_n -= 2;
}
}
if (cur_n == 1 && cur_len > 0) {
ans_l += pre1[min(cur_len, l1)][c];
} else if (cur_n == 2 && cur_len > 0) {
ans_l += pre2[min(cur_len, l2)][c];
}
cout << ans_r - ans_l << "\n";
}
return 0;
}
提出情報
| 提出日時 | |
|---|---|
| 問題 | E - Fibonacci String |
| ユーザ | kac17 |
| 言語 | C++23 (GCC 15.2.0) |
| 得点 | 450 |
| コード長 | 4149 Byte |
| 結果 | AC |
| 実行時間 | 79 ms |
| メモリ | 8260 KiB |
ジャッジ結果
| セット名 | Sample | All | ||||
|---|---|---|---|---|---|---|
| 得点 / 配点 | 0 / 0 | 450 / 450 | ||||
| 結果 |
|
|
| セット名 | テストケース |
|---|---|
| Sample | sample_01.txt |
| All | random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_07.txt, random_08.txt, random_09.txt, random_10.txt, random_11.txt, random_12.txt, random_13.txt, random_14.txt, sample_01.txt |
| ケース名 | 結果 | 実行時間 | メモリ |
|---|---|---|---|
| random_01.txt | AC | 42 ms | 3704 KiB |
| random_02.txt | AC | 43 ms | 3656 KiB |
| random_03.txt | AC | 74 ms | 3728 KiB |
| random_04.txt | AC | 73 ms | 3704 KiB |
| random_05.txt | AC | 73 ms | 3684 KiB |
| random_06.txt | AC | 73 ms | 3700 KiB |
| random_07.txt | AC | 73 ms | 3720 KiB |
| random_08.txt | AC | 73 ms | 3700 KiB |
| random_09.txt | AC | 72 ms | 3560 KiB |
| random_10.txt | AC | 73 ms | 3560 KiB |
| random_11.txt | AC | 73 ms | 3520 KiB |
| random_12.txt | AC | 79 ms | 8260 KiB |
| random_13.txt | AC | 79 ms | 8180 KiB |
| random_14.txt | AC | 79 ms | 8248 KiB |
| sample_01.txt | AC | 2 ms | 3588 KiB |