This commit is contained in:
Zengtudor 2025-08-03 14:59:41 +08:00
parent c24b145946
commit 1d13c6384a
17 changed files with 10389 additions and 0 deletions

105
src/8/3/T645386.cpp Normal file
View File

@ -0,0 +1,105 @@
#include <iostream>
#include <vector>
#include <string>
#include <numeric>
#include <algorithm>
// 使用模板化IO优化提高读写速度适用于大数据量
void setup_io() {
std::ios_base::sync_with_stdio(false);
std::cin.tie(NULL);
}
/**
* @brief 使 Manacher
*
* Manacher 线
*
*
* @param n s
* @param s
* @return long long s
*/
long long count_palindromic_substrings(int n, const std::string& s) {
long long count = 0;
// Part 1: 计算所有奇数长度的回文子串
// d1[i] 存储以 s[i] 为中心的最长回文串的半径。
// 半径为 k 表示 s[i-k+1...i+k-1] 是回文串。
// 以 s[i] 为中心的回文串数量即为其最长半径 d1[i]。
std::vector<int> d1(n);
// [l, r] 维护当前找到的所有回文串中,右端点最靠右的那个回文串的边界
for (int i = 0, l = 0, r = -1; i < n; ++i) {
// 确定初始半径 k
// 如果 i 在 [l, r] 右边只能从1开始暴力匹配
// 否则可以利用已有的信息。i 关于 (l+r)/2 的对称点是 l+r-i。
// d1[l+r-i] 是对称点的半径,但不能超过当前右边界 r。
int k = (i > r) ? 1 : std::min(d1[l + r - i], r - i + 1);
// 从半径 k 开始继续扩展
while (i - k >= 0 && i + k < n && s[i - k] == s[i + k]) {
k++;
}
d1[i] = k;
// 如果以 i 为中心的回文串右边界超过了 r, 更新 [l, r]
if (i + k - 1 > r) {
l = i - k + 1;
r = i + k - 1;
}
}
// Part 2: 计算所有偶数长度的回文子串
// d2[i] 存储以 s[i-1] 和 s[i] 之间为中心的最长回文串的半长。
// 半长为 k 表示 s[i-k...i+k-1] 是回文串。
// 以 (i-1, i) 为中心的回文串数量即为其最长半长 d2[i]。
std::vector<int> d2(n);
for (int i = 0, l = 0, r = -1; i < n; ++i) {
// 确定初始半长 k
int k = (i > r) ? 0 : std::min(d2[l + r - i + 1], r - i + 1);
// 从半长 k 开始继续扩展
while (i - k - 1 >= 0 && i + k < n && s[i - k - 1] == s[i + k]) {
k++;
}
d2[i] = k;
// 更新 [l, r]
if (i + k - 1 > r) {
l = i - k;
r = i + k - 1;
}
}
// 所有回文子串总数 = 奇数长度回文串总数 + 偶数长度回文串总数
// 使用 std::accumulate 高效求和
count = std::accumulate(d1.begin(), d1.end(), 0LL);
count += std::accumulate(d2.begin(), d2.end(), 0LL);
return count;
}
int main() {
setup_io();
int n;
std::cin >> n;
std::string s;
std::cin >> s;
// 步骤1: 计算总的操作方案数
// 对于每个 l from 1 to n, r可以取 l, l+1, ..., n共 n-l+1 种选择。
// 总数为 n + (n-1) + ... + 1 = n*(n+1)/2。
long long total_choices = (long long)n * (n + 1) / 2;
// 步骤2: 计算所有回文子串的数量 P
long long palindromic_substrings_count = count_palindromic_substrings(n, s);
// 步骤3: 根据核心公式计算最终答案
// 总的不同字符串数 = (非回文翻转产生的不同字符串数) + (回文翻转产生的不同字符串数)
// 非回文翻转有 (total_choices - P) 种,每种产生一个独一无二的字符串。
// 回文翻转有 P 种,全部只产生原字符串 s 这一个结果。
// 所以总数为 (total_choices - P) + 1。
long long distinct_strings_count = total_choices - palindromic_substrings_count + 1;
std::cout << distinct_strings_count << std::endl;
return 0;
}

98
src/8/3/T645386.md Normal file
View File

@ -0,0 +1,98 @@
为了解决这个问题,我们需要计算对给定字符串进行所有可能的翻转操作后,得到的本质不同字符串的数量。翻转操作是指选择字符串的一个子区间并将其反转。不同的翻转操作可能会产生相同的字符串,因此需要高效地计算这些字符串的去重数量。
### 方法思路
1. **问题分析**:给定一个长度为 \( n \) 的字符串,所有可能的翻转操作有 \(\frac{n(n+1)}{2}\) 种。每个翻转操作选择子串 \([l, r]\) 并将其反转。不同的操作可能产生相同的字符串,我们需要计算这些字符串的去重数量。
2. **关键观察**:如果翻转的子串是回文的,则翻转后的字符串与原串相同。否则,翻转操作会产生新的字符串。同时,不同的非回文子串翻转操作产生的字符串都是唯一的。
3. **公式推导**:本质不同字符串的总数 = 总翻转操作数 - 回文子串的数量 + 1。其中
- 总翻转操作数为 \(\frac{n(n+1)}{2}\)。
- 回文子串的数量通过 Manacher 算法计算。
- 加 1 是因为所有回文子串翻转操作只产生一个字符串(即原串)。
4. **Manacher 算法**:用于高效计算字符串中所有回文子串的数量。算法在 \( O(n) \) 时间内完成,具体步骤包括:
- 构造新字符串:在原始字符串的每个字符间插入特殊字符(如 '#'),并在首尾添加边界字符(如 '$' 和 '%')。
- 计算每个字符为中心的最长回文半径。
- 根据半径计算回文子串数量:偶数索引(原始字符)对应奇数长度回文子串,奇数索引(特殊字符)对应偶数长度回文子串。
### 解决代码
```cpp
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef long long ll;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
string s;
cin >> n >> s;
if (n == 0) {
cout << 0 << endl;
return 0;
}
ll total = (ll)n * (n + 1) / 2;
string t = "$#";
for (char c : s) {
t += c;
t += '#';
}
t += '%';
int len_t = t.size();
vector<int> p(len_t, 0);
int C = 0, R = 0;
for (int i = 1; i < len_t - 1; i++) {
int i_mirror = 2 * C - i;
if (i < R) {
p[i] = min(R - i, p[i_mirror]);
} else {
p[i] = 0;
}
while (t[i + p[i] + 1] == t[i - p[i] - 1]) {
p[i]++;
}
if (i + p[i] > R) {
C = i;
R = i + p[i];
}
}
ll pal_count = 0;
for (int i = 1; i < len_t - 1; i++) {
if (i % 2 == 0) {
pal_count += (p[i] + 1) / 2;
} else {
pal_count += p[i] / 2;
}
}
ll ans = total - pal_count + 1;
cout << ans << endl;
return 0;
}
```
### 代码解释
1. **输入处理**:读取字符串长度 \( n \) 和字符串 \( s \)。
2. **计算总翻转操作数**:公式为 \(\frac{n(n+1)}{2}\)。
3. **构造新字符串**:在原始字符串的字符之间插入 '#',并在首尾添加 '$' 和 '%',以便统一处理奇偶长度的回文子串。
4. **Manacher 算法**
- 初始化数组 `p` 存储每个字符为中心的最长回文半径。
- 使用变量 `C``R` 分别记录当前回文中心和右边界。
- 遍历新字符串,利用对称性快速计算半径,并扩展边界。
5. **统计回文子串数量**
- 对于偶数索引(对应原始字符),回文子串数量为 \((p[i] + 1) / 2\)。
- 对于奇数索引(对应插入字符),回文子串数量为 \(p[i] / 2\)。
6. **计算结果**:本质不同字符串数量 = 总翻转操作数 - 回文子串数量 + 1。
7. **输出结果**:打印最终答案。
该方案高效地解决了问题,时间复杂度为 \( O(n) \),适用于 \( n \) 最大为 \( 2 \times 10^5 \) 的情况。

65
src/8/3/T645387.cpp Normal file
View File

@ -0,0 +1,65 @@
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int mod = 1000000007;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); // 优化输入输出
int n;
cin >> n;
vector<int> l(n), r(n);
int min_h = 10000, max_h = 0;
// 读取数据并确定值域范围
for (int i = 0; i < n; i++) {
cin >> l[i] >> r[i];
min_h = min(min_h, l[i]); // 全局最小左边界
max_h = max(max_h, r[i]); // 全局最大右边界
}
long long ans = 0;
// 枚举所有可能的序列最大值h
for (int h = min_h; h <= max_h; h++) {
long long prodA = 1; // 存储A(h)所有元素≤h的序列权值和
long long prodB = 1; // 存储B(h)所有元素≤h-1的序列权值和
// 遍历每个位置
for (int i = 0; i < n; i++) {
// 计算S_i(h)a_i在[l_i, min(r_i,h)]区间内,(h - a_i + 1)的和
int R1 = min(r[i], h);
long long s1 = 0;
if (R1 >= l[i]) {
int len = R1 - l[i] + 1; // 项数
long long first = h - l[i] + 1; // 首项
long long last = h - R1 + 1; // 末项
s1 = (first + last) * len / 2; // 等差数列求和
}
// 计算T_i(h)a_i在[l_i, min(r_i,h-1)]区间内,(h - a_i + 1)的和
int R2 = min(r[i], h - 1);
long long s2 = 0;
if (R2 >= l[i]) {
int len = R2 - l[i] + 1; // 项数
long long first = h - l[i] + 1; // 首项
long long last = h - R2 + 1; // 末项
s2 = (first + last) * len / 2; // 等差数列求和
}
// 累乘结果(每一步取模防溢出)
prodA = (prodA * (s1 % mod)) % mod;
prodB = (prodB * (s2 % mod)) % mod;
}
// 容斥计算最大值恰好为h的序列权值和
long long F = (prodA - prodB + mod) % mod; // 防止负数
ans = (ans + F) % mod; // 累加到总答案
}
cout << ans << endl;
return 0;
}

1
src/8/3/array1.ans Normal file
View File

@ -0,0 +1 @@
282

4
src/8/3/array1.in Normal file
View File

@ -0,0 +1,4 @@
3
2 5
2 4
2 5

1
src/8/3/array2.ans Normal file
View File

@ -0,0 +1 @@
280630082

101
src/8/3/array2.in Normal file
View File

@ -0,0 +1,101 @@
100
83 92
21 48
60 100
26 43
14 81
39 52
4 21
11 27
10 90
70 79
11 64
1 92
22 69
42 53
5 16
33 100
6 72
68 96
32 87
5 36
36 73
28 54
68 93
81 82
76 84
47 88
61 100
47 66
4 23
20 25
6 65
47 88
41 53
5 22
4 40
53 77
7 76
16 97
23 43
13 77
40 47
16 95
9 19
59 92
50 82
17 70
49 93
11 87
74 83
65 78
25 28
66 92
30 69
58 67
59 61
50 92
45 56
28 84
49 64
46 99
15 80
1 64
8 16
15 38
1 86
11 53
24 84
19 86
22 34
21 92
15 48
11 52
3 37
37 43
21 100
5 77
67 81
46 96
24 27
30 30
2 43
1 2
6 69
4 47
10 84
35 94
1 55
6 19
17 82
36 91
70 93
54 57
68 93
3 89
66 67
15 67
16 100
9 32
65 88
26 77

1
src/8/3/array3.ans Normal file
View File

@ -0,0 +1 @@
717010692

10001
src/8/3/array3.in Normal file

File diff suppressed because it is too large Load Diff

1
src/8/3/reverse1.ans Normal file
View File

@ -0,0 +1 @@
3

2
src/8/3/reverse1.in Normal file
View File

@ -0,0 +1,2 @@
3
aab

1
src/8/3/reverse2.ans Normal file
View File

@ -0,0 +1 @@
19150

2
src/8/3/reverse2.in Normal file
View File

@ -0,0 +1,2 @@
200
oagwsbjygeoggjckybwpoycuxtsdvzwaxdvodnmymkrfjmcqljefoxlptlcexvwevmlraivqwpdrkqfifpylkynvpfjrlcuktobirivgaddctrjympikbacdipedgaynnoybkzzpiyshnewzwnkclzpczbrucjlvpcuxmzpimetwwajtfcsbjjtecacrqzvbvnlmholm

1
src/8/3/reverse3.ans Normal file
View File

@ -0,0 +1 @@
1921937

2
src/8/3/reverse3.in Normal file
View File

@ -0,0 +1,2 @@
2000
sbyjzuyosavwsdpxmsblipudhfcdnouxbkrcsjeliykbxkrtokgsvekvuowllpuqgssthhpccmlooaxuoyvjrscgdwhqbuevvyywkkmcclysyxemxkretqieixyfohdnxztylqchysqwjvxgklvqmdsneeszxwwxbulimrjhhgzgkkocjescxwkmxbivwhihnfcjcfwpwzhgqbxyojofnpzvjvptvcuacizftngmbmgiszpnrmwiweysqtbttcynrdruqzltzgaahpbzaibqsahnwlyxshnrjjojdcgfloksljbiiuvuxfqwhkacaogqiyxjcxdtrnjawcphidgeocigrasgxicoayqoxmptqhmjjipitdrucodqcflbklxqtoletyqmvwwyswwapsododwdfmgnjodmqqlnbvfuisryencllpovnajvooxkukzmxlsthfahyzkahnhoqdcejqqrqdailyrlddhuhyuqkhcqzkyigcgjunfpwxpqimgwaoszxylvkwjfdobkgecgmedlekqtnaoeqnmavxzloojsjsaihwnzektftknkhjdzslsxubizsoqlqpnerykasibrjcggtyupqlbfpmxggfipxsdfljvpvjwahuilukrmatjaqbdvmbfvmxhrtekeiyajwnyvhgrlmttbprrdsinxcotvinnzruxfyjfjqkjrkflfrayaeylqbafunbjahxilljhehfurhswovptboehezuephswwlxhxmsqhwmdhbleylrwhclkvifypslasbuvybffusmxibjsyglpkmyxpntidtxskfyzxtonamnnvokykqqzgyavydmfhsmsutvwqsqwkwexssmnzfwzsaiphgoeznpkacnfigkotyfyuepwkaivazudwhxrzkfndvkhvjgtyagyokzgxbcvjrpnatdnhflufnfxbvgmsnhgumrtkkpvellnrgttrtxqbowctrkbbevmaaaosskwpgsaezqmjvmegcexyubxloltreilbadszlfgiettwpzdpfvtussajzvnhxalpokvjjcwzhrwpufvrzkuhzhpaokxswsydjufgwxvrbyontkpgpxzikrfsofmjzthzwuaewzdbrrvurgjtsolkyybztxinikioyqyodxcpwripvhtncvkdvqoycrmispgnuyhfjrqeswnejjquwkwiduukjnpdbedixyygryyeiriegwxversiehzkajrwjkynfjrvvhrsccetumeyrljtbgyjjickcinwucbyfigkskpeitvvdurqcihlaexzxzgbpcroruqwqdkfospizhkmcoeftpjbylxrpdezjgtuyrlrkzevhncsuprynuixdtabjllklwekplocgikrgopcpgvmztzntjtsroyrntkseyedqcmgswshfskltwkqxcgofulgbbhlgqxlcmlaypjgdasldevemtrndlupgrjcmmyphaeqpjgwcegzqejmxywjxpdmhyevegdnyploifrdngnbjavkdipfancoglqpuazpyfqaawixwomynkyrgillldkpfltuwkhtlcuvxooddqtylxlcbrereguiwsakjnhpjltbvquraakavbpfylxogpqmwpjmqftmjnsegiywryjmwtvcxhynibfqwwamiwrfinbdqvsfsxaeqnfkjrfekadxckyseumofclawmvftxzuadiwxyhemihmfsxzhkbqvijfrygubaxrazeeuqruiwcegvwsauxcbgljgfqrufuahcyxbcoectzjyynuqsybgmsqymnsjtqwosmhkydmrmltmosjplnlqifbwkbmrludlrjtiltwurmnbttdvexosgiwfyjoqrgostczhxelsxtgjimifvqpyxvilxyssujajsamwuyyfkxomhwvqrfrkcrzqdydmjzksfekpyhyyeggprksgfbymvvknawnggysddsrkxnjulohuyattgpy

1
src/8/3/reverse4.ans Normal file
View File

@ -0,0 +1 @@
19230661303

2
src/8/3/reverse4.in Normal file

File diff suppressed because one or more lines are too long